微信小程序--V3支付

接入前准备

详见微信支付手册

对接支付

开发准备

  1. 下载对应的开发库wechatpay-apache-httpclient,或者到微信的官方文档点击链接下载
  2. appId(小程序中获取)
  3. appSecret(小程序中获取)
  4. openId(登录获取)
  5. mchId-商户号(商户平台中获取)
  6. mchSerialNo-商户证书序列号(商户平台中获取)
  7. gateway-预支付网关(微信的官方获取)
    如下:https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi
  8. apiV3Key-商户私钥(自己设置)
  9. 证书私钥
    在这里插入图片描述

时序图

在这里插入图片描述

着手开发

  1. 从第四步开始,我们需要向微信服务器推送一个预支付订单,在生成订单之前,我们需要做三件事:加载商户私钥、加载平台证书、初始化httpClient,需要替换调其中的参数。
@Before
public void setup() throws IOException {
    // 加载商户私钥(privateKey:私钥字符串)
    PrivateKey merchantPrivateKey = PemUtil
            .loadPrivateKey(new ByteArrayInputStream(privateKey.getBytes("utf-8")));
 
    // 加载平台证书(mchId:商户号,mchSerialNo:商户证书序列号,apiV3Key:V3密钥)
    AutoUpdateCertificatesVerifier verifier = new AutoUpdateCertificatesVerifier(
            new WechatPay2Credentials(mchId, new PrivateKeySigner(mchSerialNo, merchantPrivateKey)),apiV3Key.getBytes("utf-8"));
 
    // 初始化httpClient
    httpClient = WechatPayHttpClientBuilder.create()
            .withMerchant(mchId, mchSerialNo, merchantPrivateKey)
            .withValidator(new WechatPay2Validator(verifier)).build();
}
 
@After
public void after() throws IOException {
    httpClient.close();
}
  1. 生成预支付订单,此时我们就拿到了prepay_id,务必要保证参数的正确性,否则会出现“验签失败”的错误
/**
* 创建预支付订单
*/
@Test
public void CreateOrder() throws Exception {
   HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi");
   httpPost.addHeader("Accept", "application/json");
   httpPost.addHeader("Content-type", "application/json; charset=utf-8");

   ByteArrayOutputStream bos = new ByteArrayOutputStream();
   ObjectMapper objectMapper = new ObjectMapper();

   ObjectNode rootNode = objectMapper.createObjectNode();
   rootNode.put("mchid", MerchantConstants.MCH_ID)
           .put("appid", "wx-------------")
           .put("description", "Tiger-test")
           .put("notify_url", "https://www.weixin.qq.com/wxpay/pay.php")
           .put("out_trade_no", IdUtils.simpleUUID());
   rootNode.putObject("amount")
           .put("total", 1);
   rootNode.putObject("payer")
           .put("openid", "-----------------");

   objectMapper.writeValue(bos, rootNode);

   httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
   CloseableHttpResponse response = httpClient.execute(httpPost);

   String bodyAsString = EntityUtils.toString(response.getEntity());
   System.out.println(bodyAsString);
   createSignature(bodyAsString);
}
  1. 生成带签名的支付信息,前端后端生成都可以,我选择后端生成,要注意signType = “RSA”,不要改成MD5
/**
* 生成带签名的支付信息
*
* @param prePayId 预支付ID
* @return
*/
public Map<String, String> createSignature(String prePayId) {
   Map<String, String> prePayIdMap = JSON.parseObject(prePayId, new TypeReference<Map<String, String>>() {
   });
   String timestamp = System.currentTimeMillis() + "";
   String randomString = IdUtils.simpleUUID();

   StringBuilder paySign = new StringBuilder();    // 小程序签名
   paySign.append(AppletConstants.APP_ID).append("\n");
   paySign.append(timestamp).append("\n");
   paySign.append(randomString).append("\n");
   paySign.append(prePayIdMap.get("prepay_id")).append("\n");

   HashMap<String, String> result = new HashMap<>();
   result.put("appId", AppletConstants.APP_ID);
   result.put("timeStamp", timestamp);
   result.put("nonceStr", randomString);
   result.put("package", prePayIdMap.get("prepay_id"));
   result.put("signType", "RSA");
   result.put("paySign", paySign.toString());
   return result;
}
  1. 异步通知平台处理结果
@PostMapping("/applet/callback")
public synchronized Map callback(HttpServletRequest request) {
    // 获取请求头
    String wechatPayTimestamp = request.getHeader("Wechatpay-Timestamp");   // 时间戳
    String wechatPayNonce = request.getHeader("Wechatpay-Nonce");   // 随机字符串
    String wechatPaySignature = request.getHeader("Wechatpay-Signature");   // 应答签名
    String wechatPaySerial = request.getHeader("Wechatpay-Serial");   // 序列号

    // 给微信服务器返回的值
    HashMap<String, String> result = new HashMap<>();
    result.put("code", "FAIL");
    try {
        StringBuilder message = new StringBuilder();    // 请求报文

        BufferedReader br = request.getReader();
        String str = null;
        StringBuilder builder = new StringBuilder();
        while (true) {
            if (!((str = br.readLine()) != null)) break;
            builder.append(str);
        }

        // 构建报文
        message.append(wechatPayTimestamp).append("\n");
        message.append(wechatPayNonce).append("\n");
        message.append(builder.toString()).append("\n");

        // 验证签名
        if (!new PayUtils().signVerify(wechatPaySerial, message.toString(), wechatPaySignature)) {
            result.replace("code", "FAIL");
            result.put("message", "签名错误");
            return result;
        }

        // 解密
        String decryptResult = PayUtils.decryptOrder(builder.toString());
        if (StringUtils.isEmpty(decryptResult)) {
            result.put("message", "解密失败");
            return result;
        }

        // 验证订单,更新订单
        ObjectMapper objectMapper = new ObjectMapper();
        JsonNode jsonNode = objectMapper.readTree(decryptResult);
        String orderId = jsonNode.get("out_trade_no").textValue();
        Order order = new Order();
        order.setId(orderId);
        order.setOrderStatus("2");  // 配送中订单
        orderService.updateOrder(order);

        // 返回消息
        result.replace("code", "SUCCESS");
        result.put("message", "支付成功");
    } catch (Exception e) {
        e.printStackTrace();
    }
    return result;
}
  1. 前端接收微信返回的支付信息,进行处理(跳转页面等)。

分享代付

同理,把这一系列过程放在支付接口

鸣谢

专治八阿哥的孟老师的微信支付V3版本视频,手把手教学,十分推荐

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答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); ``` 最后,在前端页面中使用获取到的支付参数调起微信支付即可。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值