uni-app中微信支付之小程序端微信支付的实现【中】

海豚精灵https://mgo.whhtjl.com

相信大家已在网上找了各种资料,也看过了各种文档,对于整个流程我就不再重复啦,有疑惑的小伙伴可以移步微信开放平台查看详情,网页地址:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_10&index=1

废话不多说,直接上代码:

uni-app前端代码:

<template>
    <view>
        <page-head :title="title"></page-head>
        <view class="uni-padding-wrap">
            <view style="background:#FFF; padding:50rpx 0;">
				 <view class="uni-hello-text uni-center font-lg text-danger">{
   
   {vipName}}</view>
                <view class="uni-h1 uni-center uni-common-mt">
                    <text class="rmbLogo">¥</text>
                    <input class="price" type="digit" :value="price" maxlength="5" @input="priceChange" />
                </view>
            </view>
            <view class="uni-btn-v uni-common-mt">
                <!-- #ifdef MP-WEIXIN || MP-QQ -->
                <button type="primary" @click="weixinPay" :loading="loading">微信支付</button>
                <!-- #endif -->
            </view>
        </view>
    </view>
    </view>
</template>
<script>
    export default {
        data() {
            return {
                title: 'request-payment',
                loading: false,
				typeId:0,
				vipName:'',
                price: 1,
                providerList: [],
				user:'',
				baseLocation: '',
				memberCardOrders:[],
				header: { 'Content-Type': 'application/x-www-form-urlencoded' }
            }
        },
        onLoad: function(e) {
			this.baseLocation = getApp().globalData.BaseUrl;
			this.user = uni.getStorageSync('user');
			if(e.id){
				this.typeId=e.id;
			}
			if(e.typeName){
				this.vipName=e.typeName;
			}
			if(e.currentPrice){
				this.price=e.currentPrice;
			}
        },
        methods: {
			//登录
			async login() {
				// #ifdef APP-PLUS || H5
				this.$loginForAppAndH5();
				// #endif
			
				// #ifdef MP-WEIXIN
				this.$loginForWeiXinApplet();
				// #endif
			},
			//微信支付
            weixinPay() {
				    this.loading = true;
				    uni.login({
				        success: (e) => {
							let ticket = uni.getStorageSync('ticket'); //取出Cookie
							if (ticket) {
								this.header.Cookie = ticket;
								uni.request({
									url:this.baseLocation + '/api/client/pay/appletPaymentPay',
									header:this.header,
									data:{
										memberCardTypeId: this.typeId,
										payType: 'APPLETPAYMENT',
										orderAmount: this.price,
										memberCardTypeName: this.vipName,
										code:e.code
									},
								    success: (res) => {
								        if (res.data.code === 200) {
								            let paymentData = res.data.payment;
								            uni.requestPayment({
								                timeStamp: paymentData.timeStamp,
								                nonceStr: paymentData.nonceStr,
								                package: paymentData.packageValue,
								                signType: paymentData.signType,
								                paySign: paymentData.paySign,
								                success: (res) => {
													uni.showToast({
														title:'支付成功,即将跳转到会员中心...',
														icon:'none',
														duration:1000
													})
													uni.reLaunch({
														url:'membercenter'
													})
								                },
								                fail: (res) => {
								                    uni.showModal({
								                        content: "支付失败,原因为: " + res.errMsg,
								                        showCancel: false
								                    })
													return false;
								                },
								                complete: () => {
								                    this.loading = false;
								                }
								            })
								        } else {
								            uni.showModal({
								                content: res.data.message,
								                showCancel: false
								            })
											return false;
								        }
								    },
								    fail: (e) => {
								        this.loading = false;
								        uni.showModal({
								            content: "支付失败,原因为: " + e.errMsg,
								            showCancel: false
								        })
										return false;
								    }
								})
							}else{
								this.login();	
							}
				        },
				        fail: (e) => {
				            this.loading = false;
				            uni.showModal({
				                content: "支付失败,原因为: " + e.errMsg,
				                showCancel: false
				            })
							return false;
				        }
				    })
			},
			//价格计算
            priceChange(e) {
                this.price = e.detail.value;
            }
			
        }
    }
</script>

<style>
    .rmbLogo {
        font-size: 40rpx;
    }

    button {
        background-color: #007aff;
        color: #ffffff;
    }

    .uni-h1.uni-center {
        display: flex;
        flex-direction: row;
        justify-content: center;
        align-items: flex-end;
    }

    .price {
        border-bottom: 1px solid #eee;
        width: 200rpx;
        height: 80rpx;
        padding-bottom: 4rpx;
    }

    .ipaPayBtn {
        margin-top: 30rpx;
    }
</style>

我这里后端使用的SpringBoot,Maven项目,代码如下:

<!--公众号(包括订阅号和服务号) -->
<dependency>
	<groupId>com.github.binarywang</groupId>
	<artifactId>weixin-java-mp</artifactId>
	<version>2.7.0</version>
</dependency>
<!--微信支付 -->
<dependency>
	<groupId>com.github.binarywang</groupId>
	<artifactId>weixin-java-pay</artifactId>
	<version>3.0.0</version>
</dependency>
<!--微信小程序 -->
<dependency>
	<groupId>com.github.binarywang</groupId>
	<artifactId>weixin-java-miniapp</artifactId>
	<version>3.0.0</version>
</dependency>

在application.properties中配置相关信息

微信APP支付这块是需要证书,大家自行去微信开放平台配置下载后放入resources目录下,可直接用classpath:xxxxxx.p12引入

#微信小程序
wx.applet.appId=xxxxxxxxxxxxxxxx
wx.applet.appSecret=xxxxxxxxxxxxxxxx

创建实体类

package com.ltf.config;

import lombok.Data;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Data
@Component
@ConfigurationProperties(prefix = "wx.applet")
public class WeChatAppletProperties {

	/**
	 * appId
	 */
	private String appId;

	/**
	 * 公众平台密钥
	 */
	private String appSecret;

	@Override
	public String toString() {
		return ToStringBuilder.reflectionToString(this,
				ToStringStyle.MULTI_LINE_STYLE);
	}

}

创建控制层

package com.ltf.controller;

import com.ltf.common.ReqChanle;
import com.ltf.config.WeChatAppletProperties;
import com.ltf.config.WeChatPayProperties;
import com.ltf.dao.MemberCardOrdersDao;
import com.ltf.entity.MemberCardOrders;
import com.ltf.service.MemberCardOrdersService;
import com.ltf.service.MemberCardTrxorderDetailService;
import com.ltf.utils.HttpRequestUtil;
import com.ltf.utils.SingletonLoginUtils;
import com.ltf.utils.WebUtils;
import com.alibaba.fastjson.JSONObject;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.order.WxPayAppOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;

/**
 * 微信支付
 * @author xhz
 *
 */
@RestController
@RequestMapping(value = "/api/client/pay/")
public class WeChatPayController extends BaseController{

	private static final Logger logger = LoggerFactory
			.getLogger(WeChatPayController.class);
    
    @Autowired
	private WxPayService wxPayService;
	@Autowired
	private MemberCardOrdersService memberCardOrdersService;
	@Autowired
	private MemberCardOrdersDao memberCardOrdersDao;
	@Autowired
	private MemberCardTrxorderDetailService memberCardTrxorderDetailService;
	@Autowired
	private WeChatAppletProperties weChatAppletProperties;

	/**
	 * 1块钱转为 100 分
	 * 元转分
	 *
	 * @param bigDecimal 钱数目
	 * @return 分
	 */
	private int yuanToFee(BigDecimal bigDecimal) {
		return bigDecimal.multiply(new BigDecimal(100)).intValue();
	}

	/**
	 * 100分转为1块钱
	 * 分转元
	 * 
	 * @param price 钱数目
	 * @return 元
	 */
	private String feeToYuan(Integer price) {
		return BigDecimal.valueOf(Long.valueOf(price)).divide(new BigDecimal(100)).toString();
	}

	/**
	 * 小程序支付
	 * @param request
	 * @param memberCardTypeId
	 * @param payType
	 * @param orderAmount
	 * @param memberCardTypeName
	 * @param code
	 * @return
	 */
	@SuppressWarnings("static-access")
	@GetMapping(value = "appletPaymentPay")
	@ResponseBody
	public JSONObject appletPaymentPay(HttpServletRequest request,
			@RequestParam("memberCardTypeId")String memberCardTypeId,
			@RequestParam("payType")String payType,
			@RequestParam("orderAmount")String orderAmount,
			@RequestParam("memberCardTypeName")String memberCardTypeName,
			@RequestParam("code")String code
			){
		try {
			Integer userId=SingletonLoginUtils.getLoginUserId(request);
			if(userId>0){
				Map<String, String> sourceMap = new HashMap<String, String>();
				sourceMap.put("memberCardTypeId", memberCardTypeId);// 会员卡类型id
				sourceMap.put("userId", userId+ "");//用户id
				sourceMap.put("reqchanle", ReqChanle.APLLET.toString());//用户请求来源
				sourceMap.put("payType", payType);// 支付类型
				sourceMap.put("reqIp", WebUtils.getIpAddr(request));// 用户ip
				sourceMap.put("orderAmount", orderAmount);// 订单原始金额,也是实际支付金额
				sourceMap.put("memberCardTypeName", memberCardTypeName);//会员卡类型名称
				Map<String, Object> res = memberCardOrdersService.addTrxorder(request,sourceMap);
				if(res.containsKey("msg")){
					return this.formatJSON(501, "会员卡订单创建失败!", res);
				}else{
					String param="appid="+weChatAppletProperties.getAppId()+"&secret="+weChatAppletProperties.getAppSecret()+"&js_code="+code+"&grant_type=authorization_code";
					String result=HttpRequestUtil.doJsonGet("https://api.weixin.qq.com/sns/jscode2session", param);
					if(result!=null&&!"".equals(result)){
						JSONObject jsonObject1=JSONObject.parseObject(result);
						if(jsonObject1.get("openid")!=null){
							WxPayUnifiedOrderRequest orderRequest  = new WxPayUnifiedOrderRequest();
							orderRequest.setAppid(weChatAppletProperties.getAppId());
							orderRequest.setBody(memberCardTypeName);
							orderRequest.setOutTradeNo(res.get("orderNo").toString());
							orderRequest.setTradeType("JSAPI");
							orderRequest.setTotalFee(yuanToFee(new BigDecimal(orderAmount)));
							String openId=jsonObject1.get("openid").toString();
							orderRequest.setOpenid(openId);// 获取微信支付用户的openId
							orderRequest.setSpbillCreateIp(InetAddress.getLoopbackAddress().getHostAddress());
							orderRequest.setNotifyUrl("https://你的域名/api/client/pay/appletPaymentPayNotify");
							Object order = wxPayService.createOrder(orderRequest);
							res.put("payment", order);
							return this.formatJSON(200, "OK", res);
						}else{
							return this.formatJSON(500, "openId获取失败!",null);
						}
					}else{
						return this.formatJSON(500, "openId获取失败!",null);
					}
				}
			}else{
				return this.formatJSON(500, "当前登录已失效,请重新登录!",null);
			}
		} catch (Exception e) {
			logger.error("WeChatPayController.appletPaymentPay()----error", e);
			return this.formatJSON(500, "微信小程序支付时会员卡订单创建失败!",null);
		}
	}

	/**
	 *
	 * @param xmlData 小程序支付返回的流
	 * @return
	 */
	@RequestMapping(value = "appletPaymentPayNotify",method = {RequestMethod.GET,RequestMethod.POST})
	public String appletPaymentPayNotify(@RequestBody String xmlData){
		try {
			final WxPayOrderNotifyResult notifyResult = this.wxPayService.parseOrderNotifyResult(xmlData);
			//这里是存储我们发起支付时订单号的信息,所以取出来
			MemberCardOrders memberCardOrders=new MemberCardOrders();
			memberCardOrders.setOrderNo(notifyResult.getOutTradeNo());
			//根据订单号查询订单
			MemberCardOrders mco=memberCardOrdersDao.selectMemberCardOrdersByCondition(memberCardOrders);
			//验证商户id和价格,以防止篡改金额
			if(mco!=null){
				if(weChatPayProperties.getMchId().equals(notifyResult.getMchId())&&notifyResult.getTotalFee().equals(yuanToFee(mco.getSumMoney()))){
					Map<String,Object> map=new HashMap<String,Object>();
					map.put("sumMoney", feeToYuan(notifyResult.getTotalFee()));//订单总金额
					map.put("outTradeNo", notifyResult.getTransactionId());//支付宝的交易号
					map.put("orderNo", notifyResult.getOutTradeNo());//商户系统的唯一订单号
					map.put("states", notifyResult.getResultCode());//交易状态
					map.put("payTime", notifyResult.getTimeEnd());//支付时间
					//修改会员卡订单信息
					String result1=memberCardOrdersService.updateMemberCardOrderInfoForNotify(map);
					if(result1.equals("error")){
						return WxPayNotifyResponse.fail("修改会员卡订单信息失败!");
					}
					//修改会员卡订单流水信息
					String result2=memberCardTrxorderDetailService.updateMemberCardTrxorderDetaiInfoForNotify(map);
					if(result2.equals("error")){
						return WxPayNotifyResponse.fail("修改会员卡订单流水信息失败!");
					}
					//成功后回调微信信息
					return WxPayNotifyResponse.success("回调成功!");
				}else{
					return WxPayNotifyResponse.fail("商户id和价格验证不通过!");
				}
			}else{
				return WxPayNotifyResponse.fail("订单号不存在!");
			}
		} catch (WxPayException e) {
			logger.error("WeChatPayController.appletPaymentPayNotify()----error", e);
			return WxPayNotifyResponse.fail("微信小程序支付回调有误!");
		}
	}

}

源码见:https://download.csdn.net/download/qq_35393693/12667762

猜你喜欢

转载自blog.csdn.net/qq_35393693/article/details/107381995