La réalisation du paiement H5 dans WeChat Pay dans uni-app 【Suivant】

Elfe des dauphins : https://mgo.whhtjl.com

Je pense que vous avez trouvé divers documents sur Internet et lu divers documents. Je ne répéterai pas tout le processus. Si vous avez des doutes, vous pouvez vérifier les détails sur la plate-forme ouverte WeChat. Adresse Web: https: // pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=15_1

Pas beaucoup de bêtises, allez simplement au code:

Code frontal 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">
					<span class="price">¥{
   
   { price }}</span>
				</view>
			</view>
			<view class="uni-btn-v uni-common-mt">
				<!-- #ifdef H5 -->
				<button type="primary" @click="h5Pay" :loading="loading" class="flex align-center justify-center">
					<image :src="getImgUrl('/files/static/common/wx.png')" style="width: 60rpx;height: 60rpx;"></image>
					<span class="pl-1">微信H5支付</span>
				</button>
				<!-- #endif -->
			</view>
		</view>
	</view>
</template>
<script>
export default {
	data() {
		return {
			title: 'request-payment',
			loading: false,
			typeId: 0,
			vipName: '',
			price: 1,
			providerList: [],
			user: '',
			baseLocation: '',
			memberCardOrders: [],
			codeUrl: '',
			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
		},
		//微信h5支付
		async h5Pay() {
			if (this.user) {
				this.loading = true;
				const res = await this.$ajaxRequest({
					url: '/api/client/pay/h5Pay',
					data: {
						memberCardTypeId: this.typeId,
						payType: 'H5PAY',
						orderAmount: this.price,
						memberCardTypeName: this.vipName
					}
				});
				console.log('h5支付返回结果:' + JSON.stringify(res));
				if (res.data.code === 200) {
					uni.navigateTo({
						url: '../webview/webview?linkAddress=' + res.data.orderResult.mwebUrl
					});
				} else {
					uni.showToast({
						title: res.data.message,
						icon: 'none',
						duration: 3000
					});
					return false;
				}
			} else {
				this.login();
			}
		}
	}
};
</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 {
	width: 200rpx;
	height: 80rpx;
	padding-bottom: 4rpx;
}

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

Le projet SpringBoot et Maven que j'utilise pour le back-end ici, le code est le suivant:

<!--公众号(包括订阅号和服务号) -->
<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>

Configurer les informations associées dans application.properties

Le paiement de l'application WeChat nécessite un certificat. Vous pouvez accéder à la plateforme ouverte WeChat pour le configurer, le télécharger et le placer dans le répertoire des ressources. Vous pouvez l'importer directement avec classpath: xxxxxx.p12

#微信支付
wx.pay.appId=XXXXXXXXXXXXXXXXXXXXX
wx.pay.appSecret=XXXXXXXXXXXXXXXXXXXXX
wx.pay.mchId=XXXXXXXXXXXXXXXXXXXXX
wx.pay.mchKey=XXXXXXXXXXXXXXXXXXXXX
wx.pay.keyPath=classpath:apiclient_cert.p12
wx.pay.tradeType=XXXXXXXXXXX
#微信公众号
wx.mp.appId=XXXXXXXXXXXXXXXXXXXXX
wx.mp.appSecret=XXXXXXXXXXXXXXXXXXXXX

Créer une classe d'entité

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;
 
/**
 * 微信支付商户基本信息
 * @author xhz
 *
 */
@Data
@Component
@ConfigurationProperties(prefix = "wx.pay")
public class WeChatPayProperties {
 
	/**
	 * appId
	 */
	private String appId;
	/**
	 * 公众平台密钥
	 */
	private String appSecret;
	/**
	 * 商户号
	 */
	private String mchId;
	/**
	 * 商户密钥
	 */
	private String mchKey;
	/**
	 * 证书
	 */
	private String keyPath;
	/**
	 * 交易类型
	 * <pre>
	 * JSAPI--公众号支付
	 * NATIVE--原生扫码支付
	 * APP--app支付
	 * </pre>
	 */
	private String tradeType;
 
	@Override
	public String toString() {
		return ToStringBuilder.reflectionToString(this,
				ToStringStyle.MULTI_LINE_STYLE);
	}
 
}
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;

/**
 * 微信支付商户基本信息
 * @author xhz
 *
 */
@Data
@Component
@ConfigurationProperties(prefix = "wx.mp")
public class WeChatMpProperties {

	/**
	 * appId
	 */
	private String appId;

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

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

}

Injecter les informations de paiement WeChat dans le bean

package com.ltf.config;
 
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.service.impl.WxPayServiceImpl;
import me.chanjar.weixin.mp.api.WxMpConfigStorage;
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
 
/**
 * 微信支付信息注入bean中
 * @author xhz
 *
 */
@Component
public class WeChatPayConfig {
 
	@Autowired
	private WeChatPayProperties properties;
 
	@Bean
	@ConditionalOnMissingBean
	public WxPayConfig payConfig() {
		WxPayConfig payConfig = new WxPayConfig();
		payConfig.setAppId(this.properties.getAppId());
		payConfig.setMchId(this.properties.getMchId());
		payConfig.setMchKey(this.properties.getMchKey());
		payConfig.setKeyPath(this.properties.getKeyPath());
		payConfig.setTradeType(this.properties.getTradeType());
		return payConfig;
	}
 
	@Bean
	public WxPayService wxPayService(WxPayConfig payConfig) {
		WxPayService wxPayService = new WxPayServiceImpl();
		wxPayService.setConfig(payConfig);
		return wxPayService;
	}
 
	@Bean
	public WxMpService wxMpService( ){
		WxMpService wxMpService = new WxMpServiceImpl();
		wxMpService.setWxMpConfigStorage(wxMpConfigStorage());
		return wxMpService;
	}
 
	@Bean
	public WxMpConfigStorage wxMpConfigStorage(){
		WxMpInMemoryConfigStorage wxMpConfigStorage = new WxMpInMemoryConfigStorage();
		wxMpConfigStorage.setAppId(this.properties.getAppId());
		wxMpConfigStorage.setSecret(this.properties.getAppSecret());
		return wxMpConfigStorage;
	}
 
}

Créer une couche de contrôle

package com.ltf.controller;

import com.ltf.common.OrderState;
import com.ltf.common.ReqChanle;
import com.ltf.config.WeChatAppletProperties;
import com.ltf.config.WeChatMpProperties;
import com.ltf.config.WeChatPayProperties;
import com.ltf.dao.MemberCardOrdersDao;
import com.ltf.dao.MemberCardTrxorderDetailDao;
import com.ltf.entity.MemberCardOrders;
import com.ltf.entity.MemberCardTrxorderDetail;
import com.ltf.service.MemberCardOrdersService;
import com.ltf.service.MemberCardTrxorderDetailService;
import com.ltf.service.QRCodeService;
import com.ltf.utils.HttpRequestUtil;
import com.ltf.utils.SingletonLoginUtils;
import com.ltf.utils.StringUtils;
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.order.WxPayNativeOrderResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderResult;
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;
import javax.servlet.http.HttpServletResponse;

/**
 * 微信支付
 * @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 WeChatPayProperties weChatPayProperties;
	@Autowired
	private MemberCardOrdersService memberCardOrdersService;
	@Autowired
	private MemberCardOrdersDao memberCardOrdersDao;
	@Autowired
	private MemberCardTrxorderDetailDao memberCardTrxorderDetailDao;
	@Autowired
	private MemberCardTrxorderDetailService memberCardTrxorderDetailService;
	@Autowired
	private WeChatMpProperties weChatMpProperties;

	/**
	 * h5支付
	 * @param request
	 * @param memberCardTypeId
	 * @param payType
	 * @param orderAmount
	 * @param memberCardTypeName
	 * @return
	 */
	@SuppressWarnings("static-access")
	@GetMapping(value = "h5Pay")
	@ResponseBody
	public JSONObject h5Pay(HttpServletRequest request,
			HttpServletResponse response,
			@RequestParam("memberCardTypeId")String memberCardTypeId,
			@RequestParam("payType")String payType,
			@RequestParam("orderAmount")String orderAmount,
			@RequestParam("memberCardTypeName")String memberCardTypeName
			){
		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.H5.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{
					WxPayUnifiedOrderRequest orderRequest  = new WxPayUnifiedOrderRequest();
					orderRequest.setAppid(weChatMpProperties.getAppId());
					orderRequest.setMchId(weChatPayProperties.getMchId());
					orderRequest.setNonceStr(StringUtils.getRandomString(32));
					orderRequest.setBody(memberCardTypeName);
					orderRequest.setTotalFee(yuanToFee(new BigDecimal(orderAmount)));
					orderRequest.setSpbillCreateIp(getIpAddr(request));//特别注意:此处必须获取真实IP,不能为127.0.0.1,否则无法支付
					orderRequest.setNotifyUrl("https://你的域名/api/client/pay/h5PayNotify");
					orderRequest.setTradeType("MWEB");
					orderRequest.setOutTradeNo(res.get("orderNo").toString());
					orderRequest.setSceneInfo("{\"h5_info\": {\"type\":\"Wap\",\"wap_url\": \"https://你的域名\",\"wap_name\": \"网站名称\"}}");
					//发起支付
					WxPayUnifiedOrderResult orderResult=wxPayService.unifiedOrder(orderRequest);
					System.out.println("发起h5支付返回数据:"+orderResult);
					res.put("orderResult", orderResult);
					return this.formatJSON(200, "OK", res);
				}
			}else{
				return this.formatJSON(500, "当前登录已失效,请重新登录!",null);
			}
		} catch (Exception e) {
			logger.error("WeChatPayController.h5Pay()----error", e);
			return this.formatJSON(500, "h5支付时会员卡订单创建失败!",null);
		}
	}

	/**
	 *
	 * @param xmlData h5支付返回的流
	 * @return
	 */
	@RequestMapping(value = "h5PayNotify",method = {RequestMethod.GET,RequestMethod.POST})
	public String h5PayNotify(@RequestBody String xmlData){
		try {
			final WxPayOrderNotifyResult notifyResult = this.wxPayService.parseOrderNotifyResult(xmlData);
			// 支付成功,商户处理后同步返回给微信参数
			if (("SUCCESS").equals(notifyResult.getResultCode())) {
				//这里是存储我们发起支付时订单号的信息,所以取出来
				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("订单号不存在!");
				}
			}else{
				// 支付失败, 记录流水失败
				MemberCardOrders memberCardOrders=new MemberCardOrders();
				memberCardOrders.setOrderNo(notifyResult.getOutTradeNo());//商户系统的唯一订单号
				memberCardOrders.setStates(notifyResult.getResultCode());//交易状态
				memberCardOrdersDao.updateMemberCardOrderStateForNotify(memberCardOrders);
				MemberCardTrxorderDetail memberCardTrxorderDetail=new MemberCardTrxorderDetail();
				memberCardTrxorderDetail.setRequestId(notifyResult.getOutTradeNo());//商户系统的唯一订单号
				memberCardTrxorderDetail.setTrxStatus(notifyResult.getResultCode());//交易状态
				memberCardTrxorderDetailDao.updateMemberCardTrxorderStateForNotify(memberCardTrxorderDetail);
				return WxPayNotifyResponse.fail("支付失败!");
			}
		} catch (WxPayException e) {
			logger.error("WeChatPayController.h5PayNotify()----error", e);
			return WxPayNotifyResponse.fail("h5支付回调有误!");
		}
	}

    /**获取请求IP地址*/
	public String getIpAddr(HttpServletRequest request) {
		String ipAddress = null;
		ipAddress = request.getHeader("x-forwarded-for");
		if ((ipAddress == null) || (ipAddress.length() == 0)
				|| ("unknown".equalsIgnoreCase(ipAddress))) {
			ipAddress = request.getHeader("Proxy-Client-IP");
		}
		if ((ipAddress == null) || (ipAddress.length() == 0)
				|| ("unknown".equalsIgnoreCase(ipAddress))) {
			ipAddress = request.getHeader("WL-Proxy-Client-IP");
		}
		if ((ipAddress == null) || (ipAddress.length() == 0)
				|| ("unknown".equalsIgnoreCase(ipAddress))) {
			ipAddress = request.getRemoteAddr();
			if (ipAddress.equals("127.0.0.1")) {
				InetAddress inet = null;
				try {
					inet = InetAddress.getLocalHost();
				} catch (UnknownHostException e) {
					e.printStackTrace();
				}
				ipAddress = inet.getHostAddress();
			}
		}
		if ((ipAddress != null) && (ipAddress.length() > 15)) {
			if (ipAddress.indexOf(",") > 0) {
				ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
			}
		}
		return ipAddress;
	}

	/**
	 * 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();
	}

}

Voir le code source: https://download.csdn.net/download/qq_35393693/12667762

 

Je suppose que tu aimes

Origine blog.csdn.net/qq_35393693/article/details/107423518
conseillé
Classement