app实现微信支付(apiV3) 前后端

前端:

前提:微信开放平台申请appId后,到微信商户平台关联此appId

按照上图勾选和填写

支付代码如下:

pay() {
        let that = this;
          // 参数 根据自己项目更改
          let vInfo = {};
          vInfo.orderType = 1;
          vInfo.totalPrice = 0;

          // 绑定APPID
  
          uni.getProvider({
            /* 获取服务类型,可选值如下:
             * @param share: 分享
             * @param oauth: 授权登录
             * @param push: 推送
             * @param payment: 支付类型
             */
            service: 'payment',
            success: (res) => {
              if (res.provider.indexOf('wxpay') != -1) {
                uni.request({
                  url: config + `/wechat/payment`,
                  method: 'POST',
                  data: vInfo,
                  header: {
                    'Content-Type': 'application/json'
                  },
                  success(res) {
                    if (res.errMsg == 'request:ok') {
                        
                      let info = res.data;
                      var orderInfos = {
                        "appid": info.appid, // 应用ID(AppID)
                        "partnerid": info.partnerid, // 商户号(PartnerID)
                        "prepayid": info.prepayid, // 预支付交易会话ID
                        "package": info.package, // 固定值
                        "noncestr": info.noncestr, // 随机字符串
                        "timestamp": info.timestamp, // 时间戳(单位:秒)
                        "sign": info.sign, // 签名,这里用的 MD5 签名
                      };
                      uni.requestPayment({
                        provider: "wxpay",
                        orderInfo: orderInfos,
                        success(res) {
                          // 支付成功
                        },
                        fail(err) {
                          console.log("微信支付失败");
                        }
                      });
                    }
                  },
                  fail(err) {
                    console.log("支付失败:", err)
                  }

                })
              }
            }
          });

      }

后端使用java语言

添加依赖:

  <!--        微信支付SDk-->
        <dependency>
            <groupId>com.github.wechatpay-apiv3</groupId>
            <artifactId>wechatpay-apache-httpclient</artifactId>
            <version>0.4.7</version>
        </dependency>

    <!-- 微信支付java-sdk工具包 -->
        <dependency>
            <groupId>com.github.wechatpay-apiv3</groupId>
            <artifactId>wechatpay-java</artifactId>
            <version>0.2.11</version>
        </dependency>

代码:

package **************;

import cn.hutool.core.text.StrFormatter;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSONObject;
import com.car.server.config.AppPayV3Bean;
import com.car.server.config.AppWXPayConstants;
import com.car.server.entity.pay.*;
import com.car.server.service.WxPayService;
import com.car.server.utils.R;
import com.car.server.utils.pay.AesUtil;
import com.car.server.utils.pay.AppWXPaySignatureCertificateUtil;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.wechat.pay.contrib.apache.httpclient.WechatPayHttpClientBuilder;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Validator;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.notification.Notification;
import com.wechat.pay.contrib.apache.httpclient.notification.NotificationHandler;
import com.wechat.pay.contrib.apache.httpclient.notification.NotificationRequest;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;
import io.swagger.annotations.ApiModelProperty;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.util.*;

@Slf4j
@RestController
@RequestMapping("wechat")
public class AppPayController {
    private CloseableHttpClient httpClient;
    private CertificatesManager certificatesManager;
    private Verifier verifier;
    /**
     * App下单  具体下单场景查看官方文档
     *
     * @return
     * @throws Exception
     */
    @PostMapping("payment")
    public String requestwxChatPay(@RequestBody WXPayOrderReqVO obj) throws Exception {
        String title = obj.getOrderType() == 1 ? "" : obj.getOrderType() == 2 ? "" : obj.getOrderType() == 3 ? "" : "";
        PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new ByteArrayInputStream(PayConstants.privateKey.getBytes("utf-8")));
        // 获取证书管理器实例
        certificatesManager = CertificatesManager.getInstance();
        // 向证书管理器增加需要自动更新平台证书的商户信息
        certificatesManager.putMerchant(PayConstants.MCH_ID, new WechatPay2Credentials(PayConstants.MCH_ID,
                        new PrivateKeySigner(PayConstants.MCH_SERIAL_NO, merchantPrivateKey)),
                PayConstants.API_3KEY.getBytes(StandardCharsets.UTF_8));
        // 从证书管理器中获取verifier
        verifier = certificatesManager.getVerifier(PayConstants.MCH_ID);
        httpClient = WechatPayHttpClientBuilder.create()
                .withMerchant(PayConstants.MCH_ID, PayConstants.MCH_SERIAL_NO, merchantPrivateKey)
                .withValidator(new WechatPay2Validator(certificatesManager.getVerifier(PayConstants.MCH_ID)))
                .build();
        HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/app");
        httpPost.addHeader("Accept", "application/json");
        httpPost.addHeader("Content-type", "application/json; charset=utf-8");

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectMapper objectMapper = new ObjectMapper();
        //时间戳,
        String times = System.currentTimeMillis() + "";
        //订单编号(自定义 这里以时间戳+随机数)
        Random random = new Random();
        String orderSn = times+random.nextInt(1000);
        //组合请求参数JSON格式
        ObjectNode rootNode = objectMapper.createObjectNode();
        rootNode.put("mchid", PayConstants.MCH_ID)
                .put("appid", PayConstants.APP_ID)
                .put("notify_url", PayConstants.NOTIFY_URL + "notify")
                .put("description", title)
                .put("out_trade_no", orderSn);
        rootNode.putObject("amount")
                .put("total", obj.getTotalPrice()*100)
                .put("currency", "CNY");
        try {
            objectMapper.writeValue(bos, rootNode);
            httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8"));
            //获取预支付ID
            CloseableHttpResponse response = httpClient.execute(httpPost);
            String bodyAsString = EntityUtils.toString(response.getEntity());
            //微信成功响应
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == 200) {
                //时间戳
                String timestamp = System.currentTimeMillis() / 1000 + "";
                //随机字符串
                String nonce = RandomUtil.randomString(32);
                StringBuilder builder = new StringBuilder();
                // Appid
                builder.append(PayConstants.APP_ID).append("\n");
                // 时间戳
                builder.append(timestamp).append("\n");
                // 随机字符串
                builder.append(nonce).append("\n");
                JsonNode jsonNode = objectMapper.readTree(bodyAsString);
                // 预支付会话ID
                builder.append(jsonNode.get("prepay_id").textValue()).append("\n");
                //获取签名
                String sign = this.sign(builder.toString().getBytes("utf-8"), merchantPrivateKey);
                JSONObject jsonMap = new JSONObject();
                jsonMap.put("noncestr", nonce);
                jsonMap.put("timestamp", timestamp);
                jsonMap.put("prepayid", jsonNode.get("prepay_id").textValue());
                jsonMap.put("sign", sign);
                jsonMap.put("package", PayConstants.PACKAGE);
                jsonMap.put("appid", PayConstants.APP_ID);
                jsonMap.put("partnerid", PayConstants.MCH_ID);
                return jsonMap.toJSONString();//响应签名数据,前端拿着响应数据调起微信SDK
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 计算签名
     *
     * @param message
     * @param yourPrivateKey
     * @return
     */
    private String sign(byte[] message, PrivateKey yourPrivateKey) {
        try {
            Signature sign = Signature.getInstance("SHA256withRSA");
            sign.initSign(yourPrivateKey);
            sign.update(message);
            return Base64.getEncoder().encodeToString(sign.sign());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (SignatureException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        }
        return "";
    }
}
PayConstants接口:
package com.car.server.entity.pay;

/**
 * 支付参数配置
 */
public interface PayConstants {
    String NOTIFY_URL = ""; //回调地址
    String MCH_ID = ""; //商户号
    String MCH_SERIAL_NO = ""; //商户证书序列号
    String API_3KEY = "";   //Api密钥
    String APP_ID = "";     //ApId
    String PACKAGE = "Sign=WXPay";  //签名国定字符串
    String privateKey = "";//商户私钥



}
WXPayOrderReqVO:
package *******;

import io.swagger.annotations.ApiModelProperty;

import lombok.Data;
import lombok.experimental.Accessors;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

/**
 * 预支付请求类
 */
@Data
@Accessors(chain = true)
public class WXPayOrderReqVO {
    @ApiModelProperty("订单支付类型(1.** 2. ** 3. **)")
    private Integer orderType;//附加数据,回调时可根据这个数据辨别订单类型或其他

    @ApiModelProperty("总金额(单位:分)")
    private Integer totalPrice;

    @ApiModelProperty("openid")
    private String openid;

    @ApiModelProperty("商品订单号")
    private String orderSn;

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

on loading

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

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

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

打赏作者

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

抵扣说明:

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

余额充值