总结开发微信、支付宝支付全部流程

1、PC端

第一步

调用下单接口去后台下单

/pc/course/tryToSignUpCourse.do

第二步

拿到后台传过来的订单号之后判断订单的状态

订单状态分为

1、已经支付成功 success 1

2、支付中paying 2

如果订单状态是支付中

拿着orderId ,courseId跳转到支付页面

3、到达支付页面之后

第一步后去调用/pc/memberAccount/getMemberAccount.do获取账户余额

第二步调用

pc/order/getByOrderNO.do 根据订单号获取订单信息

第三步 选择微信或者支付宝,点击立即支付

调用  /pay/alipayDeposit.do进行支付,并且加入支付类型参数,是微信,或者支付宝,或者余额

后台会做相应判断

如果是余额支付:支付成功倒计时三秒立即跳回上一页

如果是微信支付:拿到后台的支付聘证数据(微信返回的),生成二位码

并且同时开启轮询查询支付成功后查询订单支付结果,如果状态变为成功,则跳回上一页

  // 微信支付返回结果
    weChatPayResult () {
      this.timer = setInterval(() => {
        const params = {
          orderNO: this.$route.query.orderNO
        }
        this.$post('/pc/order/getByOrderNO.do', params).then((res) => {
          if (res && res.status === 'PAYMENTSUCCESSED') {
            clearInterval(this.timer)
            this.paySuccessType()
          }
        })
      }, 5000)
    },

如果是支付宝

拿到后台发布会的订单号跳转到指定的二位码页面

并且同时开启轮询查询支付成功后查询订单支付结果,如果状态变为成功,则跳回上一页

 this.$post('/pay/alipayDeposit.do', {}, data).then((res) => {
        if (res) {
          let routerData = this.$router.resolve({ path: '/Alipay', query: { htmlData: res } })
          console.log(routerData)
          // 打开新页面
          window.open(routerData.href, '_ blank')
        }
      })

2、wap端

第一步

去后台下单

 this.$post('/wap/course/tryToSignUpCourse.do?t=' + new Date().getTime() + '&mm=' + res.id, data, {}).then((response) => {
              if (!response.errorCode) {
                if (response.status == 'SUCCESS') {
                  window.location.reload()
                } else if (response.status == 'PAYING') {
                  if (!this.isLogin) {
                    this.$router.togo({path: '/login', query: {lastUrl: this.$route.fullPath}})
                  } else {
                    this.$router.togo({
                      path: '/selectPayModel',
                      query: {navType: 'Curriculum', orderNO: response.order.orderNO}
                    })
                  }
                }
              }
            })
          }

第二步

拿到订单号后之后跳转到支付页面,支付页面有选择支付宝或者余额支付,选择后点击立即支付按钮

第三步

点击立即用微信支付之后,调用接口获取订单信息

 // 获取订单信息
    getorderNOInfo() {
      const params = {
        orderNO: this.$route.query.orderNO,
        t: new Date().getTime()
      }
      this.$post("/wap/order/getByOrderNO.do", params).then((res) => {
        if (res.id) {
          this.goodsType = res.goodsType
          if (res.goodsType === 'COURSE_GROUP_BUY') {
            this.totalFee = res.groupTotalFee
            this.goodsName = res.goodsName
            this.goodsId = res.goodsId
          } else {
            this.totalFee = res.totalFee
            this.goodsName = res.goodsName
            this.goodsId = res.goodsId
          }
          this.weChatPaySuccess(this.$common.getAllUrlParams().code,this.$common.getAllUrlParams().state)
        }
      })
    },

关键的一步

订单拿到成功之后微信会给予一个code 和state

this.weChatPaySuccess(this.$common.getAllUrlParams().code,this.$common.getAllUrlParams().state)

拿到code,state之后调用后台的/pay/alipayDeposit.do接口进行发起支付

 weChatPaySuccess(code,state) {
      if (!code||!state) {//为空表示没收到回调
         return;
      }
      const mystate = this.calcuMD5('wx_pay_XXX')//MD5加密
      if (mystate !== state) {
         return;
      }
      this.payTpye = 'weixin'
      let data = {
        payMode: 'WEIXIN',
        payType: 'ORDER',
        code:code,
        tradeType: 'JSAPI',
        order: {
          payFee: this.totalFee,
          orderNO: this.$route.query.orderNO,
          tradeType: 'JSAPI'
        }
      }
      this.$post('/pay/alipayDeposit.do', {}, data).then((res) => {
        if (!res.errorCode) {
            if(typeof WeixinJSBridge === "undefined"){
	                        if( document.addEventListener ){
		                        document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
	                        }else if (document.attachEvent){
		                        document.attachEvent('WeixinJSBridgeReady', onBridgeReady); 
		                        document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
	                        }
            }else{
                this.onBridgeReady(res);
            } 
        }
      })

    },
//这段代码是微信支付文档里抄过来的,用来弹出支付弹框
onBridgeReady(params) {
              var that = this
              WeixinJSBridge.invoke(
                  'getBrandWCPayRequest', {
                  "appId":'wxefdc984d5aebe82f',
                  "timeStamp":params.timestamp+'',
                  "nonceStr":params.noncestr+'',
                  "package": 'prepay_id=' + params.prepayId+'',
                  "signType":'MD5',
                  "paySign": params.sign+''
                },
                function (res) {
                // 使用以上方式判断前端返回,微信团队郑重提示:res.err_msg将在用户支付成功后返回    ok,但并不保证它绝对可靠。
                    
                  if (res.err_msg == "get_brand_wcpay_request:ok") {
                        //到这里表示支付成功,处理支付成功的后续逻辑即可
                       that.weChatPayResult();
                  } else { 
           这里表示支付失败,重新刷新页面
                     window.location.href = that.$qr + 'wap3/#/selectPayModel?orderNO=' + that.$route.query.orderNO
                  }
                }
              )
     },

返回成功之后再次查询订单状态

     // 微信支付返回结果
    weChatPayResult () {
        const params = {
          orderNO: this.$route.query.orderNO
        }
        this.$post("/wap/order/getByOrderNO.do?t="+new Date().getTime(), params).then((res) => {
          if (res && res.status === 'PAYMENTSUCCESSED') {
            this.paySuccessType()
          }
        })
    },

弹出支付成功,跳出回上级页面

  paySuccessType() {
      if (this.payTpye === 'weixin') {
        Toast('微信支付成功')
          this.$router.push({path: '/courseDetail', query: {courseId: this.goodsId}})
      } else if (this.payTpye === 'account') {
        Toast('余额支付成功')
        this.$router.goBack()
      }
    }

3、app端

第一步

调用 app/course/tryToSignUpCourse.do接口下单

//调用下单接口获取订单号
 [self.viewModel signUpCourseId:self.ID success:^(NSString *orderNO) {
        [HQWebViewLoading removeFromSuperView:weakSelf.view];
        if (STRING_ISNIL(orderNO)) {
            NSString *my_key= [NSString stringWithFormat:@"%@%ld",[self.ID stringValue],(long)[UserManager shareInstance].memberBasicVO.ID];
            [UserDefaults setInteger:0 forKey:my_key];
            //重新请求视频播放路径
            [weakSelf queryCourseDetailInfoWithIndicator:NO isRefreshPlayer:YES];
            [SKStoreReviewController requestReview];
        }else {
         //拿到订单号弹出支付页面
            [weakSelf jumpToPay:orderNO];
        }
    } Failure:^(NSError *error) {
        [HQWebViewLoading removeFromSuperView:weakSelf.view];
    }];

拿到订单号弹出支付页面

选择微信支付,支付宝支付,余额支付

调用app/pay/appDeposit.do 去微信支付宝后台获取订单号

拿到微信支付宝的订单号之后,拉起微信,支付宝 APP进行支付操作

总结所有的支付都只用到了后台的两个接口

1、app/course/tryToSignUpCourse.do 去后台下单

2、app/pay/appDeposit.do,去后台获取发起支付所需要的参数

4、后端实现 

   1)tryToSignUpCourse.do

@Override
	public TryToSignUpVO tryToSignUpCourseForPaid(int memberId, int courseId) throws CcpException {
		TryToSignUpVO sign = new TryToSignUpVO();
		CourseEntity course = courseDAO.getDetailById(courseId, memberId);

		//不能报名自己的课程
		if (course.getCourse().getMemberId().equals(memberId)) {
			throw new CcpException(CcpErrorCode.ERROR_COURSE_SHOULD_NOE_SIGNUP_SELF_ERROR);
		}

		CourseVO courseVO = convertToCourseVO(course, false);
		//判断是否已经报名
		if (courseVO.getIsSignedUp() == CcpBooleanEnum.TRUE) {
			sign.setStatus(SignUpStatuEnum.SUCCESS);
			return sign;
		}

		//判断是否免费
		FeeTypeEnum feeType = courseVO.getBasicVO().getFeeType();
		//免费
		if (feeType == FeeTypeEnum.FREE) {
			signUpCourse(memberId, courseId);

			sign.setStatus(SignUpStatuEnum.SUCCESS);

			//免费课报名,给课程作者发系统消息  TODO 免费课不发送
			//systemMessageToCourseOwner(courseVO);
		}
		//收费
		else {
			//已经创建过订单:未支付,支付中
			OrderVO oldOrder = orderService.getByMemberAndGoods(memberId, CcpModuleEnum.COURSE, courseId);

			if (null != oldOrder && oldOrder.getId() != null) {
				sign.setStatus(SignUpStatuEnum.PAYING);
				sign.setOrder(oldOrder);
			}
			//需要创建新订单
			else {
				OrderVO order = createOrderVO(courseVO, memberId);
				orderService.add(order);
				sign.setStatus(SignUpStatuEnum.PAYING);
				sign.setOrder(order);
			}

		}

		return sign;
	}

往订单表里面插入一条数据

    @Override
    public OrderVO add(OrderVO vo) throws CcpException
    {
        vo.setOrderNO(UUID.randomUUID().toString().replace("-", ""));
        vo.setCreateTime(CcpDateUO.getInstance().getCurrentTimestamp());

        TOrder tOrder = convertToEntity(vo);

        dao.insert(tOrder);

        vo.setId(tOrder.getId());
            // 插入一条订单信息到表里,订单状态为支付中 paying。。。
        processDao.insert(createOrderProcess(vo.getOrderNO(), vo.getStatus()));

        return vo;
    }

2)appDeposit.do ​​​​​​​


    /**
     * 订单付款时调用的接口
     * 1.选择了支付宝支付,调用后返回支付宝的html,使用后会自动跳转到支付宝交易页面
     * 2.选择了微信支付,调用后返回微信支付的二维码url
     * 3.仅使用内部账户额度支付,此接口直接完成支付,页面刷新
     * @param vo
     */
    @RequestMapping(value = "alipayDeposit.do", method = RequestMethod.POST)
    public void alipayDeposit(@RequestBody PayRequestVO requestVO, @PathParam("t") Long t)
    {
        try
        {
            Integer memberId = getCurrentMemberId();
            if(requestVO.getTradeType() == null){
            	requestVO.setTradeType(WeixinPayTradeTypeEnum.NATIVE);
            }
            logger.debug("alipayDeposit : "+ requestVO);
            orderCheck(requestVO, t, memberId);
            if (requestVO.getPayMode() == PayModeEnum.ZHIFUBAO)
            {
                AliPayRequestVO alipayRequestVO = new AliPayRequestVO();
                alipayRequestVO.setCreateIp(requestVO.getCreateIp());
                alipayRequestVO.setOrder(requestVO.getOrder());
                alipayRequestVO.setPayMode(requestVO.getPayMode());
                alipayRequestVO.setPayType(requestVO.getPayType());
                alipayRequestVO.setSerialNumber(requestVO.getSerialNumber());

                AliPayResponseVO responseVO = (AliPayResponseVO) payServicePolicyBO.preparePay(alipayRequestVO);
                returnString(responseVO.getsHtmlText());
            }
            else if (requestVO.getPayMode() == PayModeEnum.WEIXIN)
            {
                WeixinPayResponseVO responseVO = (WeixinPayResponseVO) payServicePolicyBO.preparePay(requestVO);
                if(WeixinPayTradeTypeEnum.JSAPI == requestVO.getTradeType()){
                	logger.debug("alipayDeposit getPrepareResp:"+responseVO.getPrepareResp());
                	returnJSON(responseVO.getPrepareResp());
                }else{
                	logger.debug("alipayDeposit getCodeUrl:"+responseVO.getPrepareResp().getCodeUrl());
                	returnObject(responseVO.getPrepareResp().getCodeUrl());
                }
                return;
            }
            else if (requestVO.getPayMode() == PayModeEnum.ACCOUNT)
            {
                //报名成功则设置订单支付成功,内部会调用公共的updateStatus,并在完成支付后执行各自业务
                orderBO.setOrderSuccessForAccountPay(memberId, requestVO.getOrder(), requestVO.getOrder().getBusinessType());
                //订单已经完成
                returnSuccess();
            }
            else
            {
                returnFail();
                return;
            }
        }
        catch (Exception e)
        {
            returnError(CcpModuleEnum.MEMBER_ACCOUNT, e);
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值