Java实现微信支付、退款(小程序支付JSAPI-V3-整合微信sdk开发)

一、废话不多说,直接上教程:

写代码之前首先要明白微信支付的支付流程。

二、支付流程:

小程序调用后端预支付接口 => 预支付接口调用成功返回给小程序支付凭证id => 小程序拿到支付凭证调用微信后台支付接口 => 小程序支付成功后,微信后台执行支付回调将支付订单信息返回(预支付调用微信后台是需要传入支付成功后自己本地的回调接口地址,可以在回调接口里设置自己的业务逻辑)

三、退款流程:

服务端自定义设置商户退款单号进行退款申请=>服务端通过微信退款sdk对微信服务器发起验签请求=>退款成功后,微信后台执行退款回调将退款信息返回(退款地址回调微信后台是需要传入退款申请成功后自己本地的回调接口地址,可以在回调接口里设置自己的业务逻辑)

四、官方文档:

微信小程序支付官方文档

如果我们按照微信支付官方文档去一步步写会很慢很繁琐,我教大家使用微信支付官网推荐java-sdk工具包去实现。

微信支付java-sdk工具包

五、开始手撸代码:

1.导入依赖
Gradle:
implementation 'com.github.wechatpay-apiv3:wechatpay-java:0.2.11'
Maven:
<dependency>
  <groupId>com.github.wechatpay-apiv3</groupId>
  <artifactId>wechatpay-java</artifactId>
  <version>0.2.11</version>
</dependency>
2.配置微信支付前必要的密钥和商户信息
资源文件配置:

在这里插入图片描述

# 微信小程序支付配置信息
wx:
  # 微信小程序appid
  app-id: wx************
  # 商户号
  mch-id: ************
  # 证书序列号
  mch-serial-no: ************
  # 小程序密钥
  app-secret: ************
  # apiV3密钥
  api-key: ************
  # 回调接口地址
  notify-url: https://************/wxpay/payNotify
  # 退款回调接口地址
  refund-notify-url: https://************/wxpay/refund/payNotify
  # 证书地址
  key-path: ************/src/main/resources/cert/apiclient_key.pem
  cert-path: ************/src/main/resources/cert/apiclient_key.pem
  cert-p12-path: ************/src/main/resources/cert/apiclient_key.pem

获取配置信息:

@Component
@ConfigurationProperties(prefix = "wx")
@Data
@ToString
public class WxPayV3Bean {

	private String appId;

	private String mchId;

	private String mchSerialNo;

	private String appSecret;

	private String apiKey;

	private String notifyUrl;

	private String refundNotifyUrl;

	private String keyPath;

}

3.创建接口请求类和返回类

查看官方文档,查看调用微信支付时需要传哪些必传的参数。
在这里插入图片描述

预支付请求类:

@Data
@Accessors(chain = true)
public class WXPayOrderReqVO {

	@Schema(description = "订单支付类型(1.申请保证金 2. 客户保证金)",required = true)
	@NotBlank(message = "订单支付类型不能为空!")
	private String orderType;//附加数据,回调时可根据这个数据辨别订单类型或其他

	@Schema(description = "总金额(单位:分)",required = true)
	@NotNull(message = "总金额不能为空!")
	private Integer totalPrice;

	@Schema(description = "商品名称",required = true)
	@NotBlank(message = "商品名称不能为空!")
	private String goodsName;

	@Schema(description = "openid",required = true)
	@NotBlank(message = "openId不能为空!")
	private String openId;

	@Schema(description = "商品订单号",required = true)
	@NotNull(message = "商品订单号不能为空!")
	private Long orderSn;
}

预退款请求类:
@Data
@Accessors(chain = true)
public class WXRefundOrderReqVO {

	/**
	 * 微信支付订单号,微信支付订单号和商家订单号二选一
	 */
	@Schema(description = "微信支付订单号")
	private String transactionId;

	/**
	 * 商家订单号,对应 out_trade_no,
	 */
	@Schema(description = "商家订单号")
	private String orderId;

	/**
	 * 商户退款单号,对应out_refund_no
	 */
	@Schema(description = "商户退款单号")
	private String outRefundNo;

	/**
	 * 退款原因,选填
	 */
	@Schema(description = "退款原因")
	private String reason;

	/**
	 * 回调地址
	 */
	@Schema(description = "回调地址")
	private String notify;

	/**
	 * 退款金额
	 */
	@Schema(description = "退款金额")
	private Integer refundMoney;

	/**
	 * 原订单金额,必填
	 */
	@Schema(description = "原订单金额")
	private Integer totalMoney;
}

由于使用的这个sdk工具类里面有返回类,可以不用自己创建返回类。

这里我自己创了个返回类。

预支付返回类:

@Data
@Accessors(chain = true)
public class WxPayRespVO implements Serializable {

	private static final long serialVersionUID = 1L;
	/**
	 * 预支付交易会话标识小程序下单接口返回的prepay_id参数值
	 */
	@Schema(description = "预支付交易会话标识小程序下单接口返回的prepay_id参数值")
	private String prepayId;
	/**
	 * 随机字符串
	 */
	@Schema(description = "随机字符串")
	private String nonceStr;
	/**
	 * 时间戳
	 */
	@Schema(description = "时间戳")
	private Long timeStamp;
	/**
	 * 签名
	 */
	@Schema(description = "签名")
	private String paySign;
}

预退款返回类(可不用):

@Data
@Accessors(chain = true)
public class WXRefundOrderRespVO {
	/**
	 * 微信支付退款号
	 */
	@Schema(description = "微信支付退款号")
	private String refundId;

	/**
	 * 商户退款单号
	 */
	@Schema(description = "商户退款单号")
	private String outRefundNo;

	/**
	 * 微信支付订单号
	 */
	@Schema(description = "微信支付订单号")
	private String transactionId;

	/**
	 * 商户订单号
	 */
	@Schema(description = "商户订单号")
	private String outTradeNo;

	/**
	 * 退款渠道
	 */
	@Schema(description = "退款渠道")
	private String channel;

	/**
	 * 退款入账账户
	 */
	@Schema(description = "退款入账账户")
	private String userReceivedAccount;

	/**
	 * 退款成功时间
	 */
	@Schema(description = "退款成功时间")
	private String successTime;

	/**
	 * 退款创建时间
	 */
	@Schema(description = "退款创建时间")
	private String createTime;

	/**
	 * 退款状态
	 */
	@Schema(description = "退款状态")
	private String status;

	/**
	 * 资金账户
	 */
	@Schema(description = "资金账户")
	private String fundsAccount;
}

工具类:

/**
 * @project 小程序支付
 * @Classname WXPayUtil
 * @Description TODO
 * @Author: whl
 * @CreateTime: 2023-10-16  16:00
 */
public class WXPayUtil {

	//随机字符串设置
	private static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

	private static final Random RANDOM = new SecureRandom();


	public static String getSign(String signatureStr,String privateKey) throws InvalidKeyException, NoSuchAlgorithmException, SignatureException, IOException, URISyntaxException {
		//replace 根据实际情况,不一定都需要
		String replace = privateKey.replace("\\n", "\n");
		PrivateKey merchantPrivateKey = PemUtil.loadPrivateKeyFromPath(replace);
		Signature sign = Signature.getInstance("SHA256withRSA");
		sign.initSign(merchantPrivateKey);
		sign.update(signatureStr.getBytes(StandardCharsets.UTF_8));
		return Base64Utils.encodeToString(sign.sign());
	}

	/**
	 * 获取随机字符串 Nonce Str
	 *
	 * @return String 随机字符串
	 */
	public static String generateNonceStr() {
		char[] nonceChars = new char[32];
		for (int index = 0; index < nonceChars.length; ++index) {
			nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length()));
		}
		return new String(nonceChars);
	}

}

4.开始写支付接口
Controller层:
预支付:
	/**
	 * 微信预支付测试接口
	 * @return R
	 */
	@Operation(summary = "微信预支付测试接口" , description = "微信预支付测试接口" )
	@SysLog("微信预支付测试接口" )
	@PostMapping("/createOrder")
	public R<WxPayRespVO> createOrder(@RequestBody @Validated WXPayOrderReqVO req) throws Exception {
		return R.ok(wxPayService.createOrder(req));
	}
支付回调:
	/**
	 * 微信支付回调
	 * @return R
	 */
	@Operation(summary = "微信支付回调" , description = "微信支付回调" )
	@SysLog("微信支付回调" )
	@PostMapping("/payNotify")
	public R payNotify(HttpServletRequest request) throws Exception {
		wxPayService.payNotify(request);//注意:回调接口需要暴露到公网上,且要放开token验证
		return R.ok();
	}
Service、ServiceImpl层:
欲支付:

Service

	/**
	 * 功能描述:
	 * 〈微信预支付〉
	 * @Param: [req]
	 * @Return: [WxPayRespVO]
	 * @Author: whl
	 * @Date: 2023/10/10 13:46
	 */
	WxPayRespVO createOrder(WXPayOrderReqVO req) throws Exception;

ServiceImpl


	@Override
	public WxPayRespVO createOrder(WXPayOrderReqVO req) throws Exception {
		try {
			// 使用自动更新平台证书的RSA配置
			// 一个商户号只能初始化一个配置,否则会因为重复的下载任务报错
			Config config =
					new RSAAutoCertificateConfig.Builder()
							.merchantId(wxPayV3Bean.getMchId())
							// 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
							.privateKeyFromPath(wxPayV3Bean.getKeyPath())
							.merchantSerialNumber(wxPayV3Bean.getMchSerialNo())
							.apiV3Key(wxPayV3Bean.getApiKey())
							.build();
			// 构建service
			JsapiService service = new JsapiService.Builder().config(config).build();
			// request.setXxx(val)设置所需参数,具体参数可见Request定义
			PrepayRequest request = new PrepayRequest();
			Amount amount = new Amount();
			amount.setTotal(req.getTotalPrice());
			request.setAmount(amount);
			request.setAppid(wxPayV3Bean.getAppId());
			request.setMchid(wxPayV3Bean.getMchId());
			request.setDescription(req.getGoodsName());
			request.setNotifyUrl(wxPayV3Bean.getNotifyUrl());
			request.setOutTradeNo(req.getOrderSn().toString());
			request.setAttach(req.getOrderType());
			Payer payer = new Payer();
			payer.setOpenid(req.getOpenId());
			request.setPayer(payer);
			// 调用下单方法,得到应答
			// 调用微信sdk接口,生成预支付交易单
			PrepayResponse response = service.prepay(request);
			WxPayRespVO vo = new WxPayRespVO();
			Long timeStamp = System.currentTimeMillis() / 1000;
			vo.setTimeStamp(timeStamp);
			String substring = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
			vo.setNonceStr(substring);
			String signatureStr = Stream.of(wxPayV3Bean.getAppId(), String.valueOf(timeStamp), substring, "prepay_id=" + response.getPrepayId())
					.collect(Collectors.joining("\n", "", "\n"));
			String sign = WXPayUtil.getSign(signatureStr, wxPayV3Bean.getKeyPath());
			vo.setPaySign(sign);
			vo.setPrepayId("prepay_id=" + response.getPrepayId());
			return vo;
		}catch (ServiceException e){
			JSONObject parse = JSONObject.parseObject(e.getResponseBody());
			throw new ResultException(ResultEnum.ERROR,parse.getString("message"));
		}catch (Exception e){
			throw new ResultException(ResultEnum.ERROR,e.toString());
		}
	}

这个签名是工具类生成的,之前找v3版本的生成签名找半天才找到,这个特别难找。

注意:这里有个特别大的一个坑,大家一定要注意。JSONObject千万要引fastjson2的包,之前没注意引用的jsonfast的包测试环境一直报错,特别坑。找了半天才找到,直接当场破防。

支付回调:

Service

	/**
	 * 功能描述:
	 * 〈微信预支付〉
	 * @Param: [req]
	 * @Return: [WxPayRespVO]
	 * @Author: whl
	 * @Date: 2023/10/10 13:46
	 */
	WxPayRespVO createOrder(WXPayOrderReqVO req) throws Exception;

ServiceImpl


	@Override
	public void payNotify(HttpServletRequest request) throws Exception {
		try {
			//读取请求体的信息
			ServletInputStream inputStream = request.getInputStream();
			StringBuffer stringBuffer = new StringBuffer();
			BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
			String s;
			//读取回调请求体
			while ((s = bufferedReader.readLine()) != null) {
				stringBuffer.append(s);
			}
			String s1 = stringBuffer.toString();
			String timestamp = request.getHeader(WECHAT_PAY_TIMESTAMP);
			String nonce = request.getHeader(WECHAT_PAY_NONCE);
			String signType = request.getHeader("Wechatpay-Signature-Type");
			String serialNo = request.getHeader(WECHAT_PAY_SERIAL);
			String signature = request.getHeader(WECHAT_PAY_SIGNATURE);
			// 如果已经初始化了 RSAAutoCertificateConfig,可直接使用
			// 没有的话,则构造一个
			log.error(JSON.toJSONString(wxPayV3Bean));
			NotificationConfig config = new RSAAutoCertificateConfig.Builder()
					.merchantId(wxPayV3Bean.getMchId())
					.privateKeyFromPath(wxPayV3Bean.getKeyPath())
					.merchantSerialNumber(wxPayV3Bean.getMchSerialNo())
					.apiV3Key(wxPayV3Bean.getApiKey())
					.build();
			// 初始化 NotificationParser
			NotificationParser parser = new NotificationParser(config);
			RequestParam requestParam=new RequestParam.Builder()
					.serialNumber(serialNo)
					.nonce(nonce)
					.signature(signature)
					.timestamp(timestamp)
					// 若未设置signType,默认值为 WECHATPAY2-SHA256-RSA2048
					.signType(signType)
					.body(s1)
					.build();
			Transaction parse = parser.parse(requestParam, Transaction.class);
			System.out.println("parse = " + parse);
			//parse.getTradeState().equals("SUCCESS");说明支付成功
			if (parse.getTradeState().equals(Transaction.TradeStateEnum.SUCCESS)){
			//你的业务代码
			}
		} catch (Exception e) {
			throw new ResultException(ResultEnum.ERROR,e.toString());
		}
	}
5.开始写退款接口
Controller层:
退款接口:
	/**
	 * 退款
	 * @param id id(这里可以是你业务的订单id或者就商户下的退款id,具体看你的业务)
	 * @return R
	 */
	@Operation(summary = "交易订单退款申请" , description = "交易订单退款申请" )
	@SysLog("交易订单退款申请" )
	@GetMapping("/reviewRefund/{id}" )
	public R reviewRefundById(@PathVariable("id" ) String id) throws Exception {
		return R.ok(wxPayService.refundOrder(id));
	}
退款回调接口:
	/**
	 * 微信退款回调
	 * @return R
	 */
	@Operation(summary = "微信退款回调" , description = "微信退款回调" )
	@SysLog("微信退款回调" )
	@PostMapping("/refund/payNotify")
	public R refundPayNotify(HttpServletRequest request) throws Exception {
		wxPayService.refundNotify(request);//注意:回调接口需要暴露到公网上,且要放开token验证
		return R.ok();
	}

退款涉及我的部分业务代码,这里就不一一展示了,具体传参可以看我写的退款请求类

Service、ServiceImpl层:
退款申请:

Service

	/**
	 * 功能描述:
	 * 〈微信退款〉
	 * @Param: [req]
	 * @Return: [void]
	 * @Author: whl
	 * @Date: 2023/10/12 15:46
	 */
	WXRefundOrderRespVO refund(WXRefundOrderReqVO refundOrder) throws Exception;

ServiceImpl


	/**
	 * 功能描述:
	 * 〈微信退款〉
	 * @Param: [req]
	 * @Return: [void]
	 * @Author: whl
	 * @Date: 2023/10/12 15:46
	 */
	@Override
	public WXRefundOrderRespVO refund(WXRefundOrderReqVO refundOrder) throws Exception {
		try {
			// 使用自动更新平台证书的RSA配置
			// 一个商户号只能初始化一个配置,否则会因为重复的下载任务报错
			Config config =
					new RSAAutoCertificateConfig.Builder()
							.merchantId(wxPayV3Bean.getMchId())
							//使用 SDK 不需要计算请求签名和验证应答签名
							// 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
							.privateKeyFromPath(wxPayV3Bean.getKeyPath())
							.merchantSerialNumber(wxPayV3Bean.getMchSerialNo())
							.apiV3Key(wxPayV3Bean.getApiKey())
							.build();
			// 构建退款service
			RefundService service = new RefundService.Builder().config(config).build();
			// request.setXxx(val)设置所需参数,具体参数可见Request定义
			//构建退款请求
			CreateRequest request = new CreateRequest();
			//构建订单金额信息
			AmountReq amountReq = new AmountReq();
			//退款金额
			amountReq.setRefund(Long.valueOf(refundOrder.getRefundMoney()));
			//原订单金额
			amountReq.setTotal(Long.valueOf(refundOrder.getTotalMoney()));
			//货币类型(默认人民币)
			amountReq.setCurrency("CNY");
			request.setAmount(amountReq);
			//商户退款单号
			request.setOutRefundNo(String.valueOf(refundOrder.getOutRefundNo()));
			//退款通知回调地址
			request.setNotifyUrl(wxPayV3Bean.getRefundNotifyUrl());
			// 调用退款方法,得到应答
			// 调用微信sdk接口
			Refund refund = service.create(request);
			//接收退款返回参数
			Refund refundResponse = new Refund();
			refundResponse.setStatus(refund.getStatus());
			if (refundResponse.getStatus().equals(Status.SUCCESS)){
				//说明退款成功,开始接下来的业务操作
				WXRefundOrderRespVO refundOrderRespVO = new WXRefundOrderRespVO();
				//你的业务代码
				return refundOrderRespVO;
			}
		}catch (ServiceException e){
			JSONObject parse = JSONObject.parseObject(e.getResponseBody());
			throw new ResultException(ResultEnum.ERROR,parse.getString("message"));
		}catch (Exception e){
			throw new ResultException(ResultEnum.ERROR,e.toString());
		}
		return null;
	}
退款回调:

Service

	/**
	 * 功能描述:
	 * 〈微信退款回调〉
	 * @Param: [request, response]
	 * @Return: [void]
	 * @Author: whl
	 * @Date: 2023/10/13 10:46
	 */
	void refundNotify(HttpServletRequest request) throws Exception ;

ServiceImpl


	/**
	 * 功能描述:
	 * 〈微信退款回调〉
	 * @Param: [request, response]
	 * @Return: [void]
	 * @Author: whl
	 * @Date: 2023/10/13 10:46
	 */
	@Override
	public void refundNotify(HttpServletRequest request) throws Exception {
		try {
			//读取请求体的信息
			ServletInputStream inputStream = request.getInputStream();
			StringBuffer stringBuffer = new StringBuffer();
			BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
			String s;
			//读取回调请求体
			while ((s = bufferedReader.readLine()) != null) {
				stringBuffer.append(s);
			}
			String s1 = stringBuffer.toString();
			String timestamp = request.getHeader(WECHAT_PAY_TIMESTAMP);
			String nonce = request.getHeader(WECHAT_PAY_NONCE);
			String signType = request.getHeader("Wechatpay-Signature-Type");
			String serialNo = request.getHeader(WECHAT_PAY_SERIAL);
			String signature = request.getHeader(WECHAT_PAY_SIGNATURE);
			// 如果已经初始化了 RSAAutoCertificateConfig,可直接使用
			// 没有的话,则构造一个
			log.error(JSON.toJSONString(wxPayV3Bean));
			NotificationConfig config = new RSAAutoCertificateConfig.Builder()
					.merchantId(wxPayV3Bean.getMchId())
					.privateKeyFromPath(wxPayV3Bean.getKeyPath())
					.merchantSerialNumber(wxPayV3Bean.getMchSerialNo())
					.apiV3Key(wxPayV3Bean.getApiKey())
					.build();
			// 初始化 NotificationParser
			NotificationParser parser = new NotificationParser(config);
			RequestParam requestParam=new RequestParam.Builder()
					.serialNumber(serialNo)
					.nonce(nonce)
					.signature(signature)
					.timestamp(timestamp)
					// 若未设置signType,默认值为 WECHATPAY2-SHA256-RSA2048
					.signType(signType)
					.body(s1)
					.build();
			RefundNotification parse = parser.parse(requestParam, RefundNotification.class);
			System.out.println("parse = " + parse);
			//parse.getRefundStatus().equals("SUCCESS");说明退款成功
			if (parse.getRefundStatus().equals(Transaction.TradeStateEnum.SUCCESS)){
				//你的业务代码
			}
		} catch (Exception e) {
			throw new ResultException(ResultEnum.ERROR,e.toString());
		}
	}

自此整合微信支付、退款流程就全部完毕,又由本次是基于微信sdk的开发,所有省略了大量重复接口请求的编写和签名的验证等,代码相对精简,便于开发学习

  • 5
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 21
    评论
### 回答1: 微信小程序支付api-v3微信提供的一种支付方式,它基于RESTful风格的API设计,使用HTTP协议传输数据,全部使用JSON格式,具有优秀的跨平台性能和安全性。本文将为大家提供微信小程序支付api-v3 php的完整代码。 微信小程序支付api-v3 php完整代码: 首先,需要获取商户的API密钥和证书文件,然后设置请求头信息,代码如下: $merchant_api_secret = 'Your Secret Key'; //商户API密钥 $merchant_cert_file = 'path/to/cert.pem'; //商户证书文件路径 $merchant_key_file = 'path/to/key.pem'; //商户密钥文件路径 $timestamp = time(); $nonce_str = uniqid(); $signature = generate_signature($merchant_api_secret, $timestamp, $nonce_str, $http_method, $http_uri, $query_string, $body); $header = array( 'Authorization: ' . $authorization, 'Accept: application/json', 'Content-Type: application/json', 'User-Agent: your-device', 'Wechatpay-Serial: your-certificate-serial-number', 'Wechatpay-Timestamp: ' . $timestamp, 'Wechatpay-Nonce: ' . $nonce_str, 'Wechatpay-Signature: ' . $signature, ); 然后,我们需要调用微信小程序支付api-v3接口,具体如下: $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $api_url); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM'); curl_setopt($ch, CURLOPT_SSLCERT, $merchant_cert_file); curl_setopt($ch, CURLOPT_SSLKEY, $merchant_key_file); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 30); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $http_method); if (!empty($body)){ curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body)); } $response = curl_exec($ch); $status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($status_code !== 200){ throw new Exception('微信小程序支付api-v3调用错误,错误代码' . $status_code); } $response_payload = json_decode($response, true); curl_close($ch); 以上就是微信小程序支付api-v3 php的完整代码,通过以上代码可以实现微信小程序支付api-v3的接口调用,实现支付等操作。同时需要注意的是,具体代码需要根据自己的实际情况进行调整。 ### 回答2: 微信小程序支付API-v3是一套用于支付的接口,支持PHP语言,这里提供完整的代码实现。 在使用微信小程序支付API-v3前需要进行身份验证,将私钥转换为PKCS8格式和获取API证书,并将两者合成一个PEM格式的文件。接下来就可以创建支付订单并进行支付了。 以下是PHP代码的示例: ```php <?php require_once "wxpayloader.php"; $wxpayConfig = new WxPayConfig(); // 公众号ID $wxpayConfig->setAppId("your app id"); // 商户号 $wxpayConfig->setMchId("your mch id"); // 商户API秘钥 $wxpayConfig->setApiKey("your api key"); // 商户API证书路径 $wxpayConfig->setSslCertPath("path/to/your/apiclient_cert.pem"); // 商户API证书密钥路径 $wxpayConfig->setSslKeyPath("path/to/your/apiclient_key.pem"); // 微信支付平台API证书路径 $wxpayConfig->setSslRootCaPath("path/to/your/rootca.pem"); // 接口请求地址 $wxpayConfig->setApiUrl("https://api.mch.weixin.qq.com/"); // 验证商户API证书 $result = WxPayApi::sslVerify($wxpayConfig); if($result['result'] != 0) { die("SSL证书验证失败:" . $result['errmsg']); } // 创建订单 $out_trade_no = "20170525" . rand(10000, 99999); $total_fee = 1; $trade_type = "JSAPI"; // 交易类型为小程序支付 $notify_url = "http://your.domain.com/weixin/paynotify.php"; // 支付结果通知URL $wxpayData = new WxPayData(); $wxpayData->setBody("test"); $wxpayData->setOutTradeNo($out_trade_no); $wxpayData->setTotalFee($total_fee); $wxpayData->setTradeType($trade_type); $wxpayData->setNotifyUrl($notify_url); $wxpayData->setOpenid("your openid"); // 用户的openid,小程序通过wx.login获取 // 统一下单 $result = WxPayApi::unifiedOrder($wxpayConfig, $wxpayData); if($result['return_code'] != 'SUCCESS' || $result['result_code'] != 'SUCCESS') { die("统一下单失败:" . $result['err_code_des']); } // 获取微信小程序支付参数 $prepay_id = $result["prepay_id"]; $wxpayData = new WxPayData(); $wxpayData->setAppId($wxpayConfig->getAppId()); $wxpayData->setTimeStamp(time()); $wxpayData->setNonceStr(WxPayApi::generateNonceStr()); $wxpayData->setPackage("prepay_id=" . $prepay_id); $wxpayData->setSignType("RSA"); // 生成签名 $sign = WxPayApi::generateSignature($wxpayData, $wxpayConfig); // 将签名加到数据包中 $wxpayData->setPaySign($sign); // 返回小程序支付参数 echo json_encode($wxpayData->getValues()); ``` 以上代码首先创建了WxPayConfig对象,将商户号、API密钥、API证书路径等信息设置进去。然后创建订单数据包,通过WxPayApi::unifiedOrder方法提交到微信支付平台统一下单。如果成功,则获取预支付ID,按照微信小程序支付的规定生成签名,再将签名加到数据包中,最终返回给小程序,由小程序前端发起支付请求。 获取API证书和PKCS8格式私钥的方法,请参考微信支付平台官方文档。 ### 回答3: 微信小程序支付 API-v3 提供了一种安全、高效、简便的支付方式,帮助开发者更好地满足用户需求。以下是微信小程序支付 API-v3 PHP 完整代码。 首先,要使用微信小程序支付 API-v3,需要先在微信支付商户平台上注册并开通服务。 接下来,下载 PHP SDK 安装包,将下载得到的文件解压后,将文件夹内的文件复制到项目代码所在的目录中。 在代码中导入 SDK 中的类库: ```php require_once "lib/WxPay.Api.php"; require_once "lib/WxPay.Data.php"; ``` 接着,需要通过商户号和 API 密钥进行身份验证: ```php $config = new WxPayConfig(); $config->SetMerchantId("商户号"); $config->SetKey("API密钥"); ``` 然后,实例化一个统一下单对象,并设置相关支付参数: ```php $input = new WxPayUnifiedOrder(); $input->SetBody("商品描述"); // 商品描述 $input->SetAttach("附加数据"); // 附加数据 $input->SetOut_trade_no("商户订单号"); // 商户订单号 $input->SetNotify_url("回调URL"); // 回调URL $input->SetTotal_fee("总金额"); // 总金额(单位:分) $input->SetTrade_type("JSAPI"); // 交易类型 $input->SetOpenid("用户openid"); // 用户openid ``` 接着,调用统一下单 API 并获取支付参数: ```php $order = WxPayApi::unifiedOrder($config, $input); $prepayId = $order["prepay_id"]; $nonceStr = WxPayApi::getNonceStr(); $timeStamp = time(); $package = "prepay_id=" . $prepayId; $signType = "HMAC-SHA256"; $paySign = WxPayApi::getPaySign($config, $nonceStr, $package, $signType, $timeStamp); ``` 最后,在前端页面中使用获取到的支付参数调起微信支付即可。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三横同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值