Files
Genarrative/.codex/skills/wechatpay-basic-payment/references/2-服务商/示例代码/Java/1-JSAPI支付/PartnerJsapiPrepay.java
2026-05-15 03:35:30 +08:00

267 lines
9.0 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.java.demo;
import com.java.utils.WXPayUtility; // 引用微信支付工具库参考https://pay.weixin.qq.com/doc/v3/partner/4014985777
import com.google.gson.annotations.SerializedName;
import com.google.gson.annotations.Expose;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* JSAPI下单
*/
public class PartnerJsapiPrepay {
private static String HOST = "https://api.mch.weixin.qq.com";
private static String METHOD = "POST";
private static String PATH = "/v3/pay/partner/transactions/jsapi";
public static void main(String[] args) {
// TODO: 请准备商户开发必要参数参考https://pay.weixin.qq.com/doc/v3/partner/4013080340
PartnerJsapiPrepay client = new PartnerJsapiPrepay(
"19xxxxxxxx", // 商户号,是由微信支付系统生成并分配给每个商户的唯一标识符,商户号获取方式参考 https://pay.weixin.qq.com/doc/v3/partner/4013080340
"1DDE55AD98Exxxxxxxxxx", // 商户API证书序列号如何获取请参考 https://pay.weixin.qq.com/doc/v3/partner/4013058924
"/path/to/apiclient_key.pem", // 商户API证书私钥文件路径本地文件路径
"PUB_KEY_ID_xxxxxxxxxxxxx", // 微信支付公钥ID如何获取请参考 https://pay.weixin.qq.com/doc/v3/partner/4013038589
"/path/to/wxp_pub.pem" // 微信支付公钥文件路径,本地文件路径
);
PartnerAPIv3PartnerJsapiPrepayRequest request = new PartnerAPIv3PartnerJsapiPrepayRequest();
request.spAppid = "wx8888888888888888";
request.spMchid = "1230000109";
request.subAppid = "wxd678efh567hg6999";
request.subMchid = "1900000109";
request.description = "Image形象店-深圳腾大-QQ公仔";
request.outTradeNo = "1217752501201407033233368018";
request.timeExpire = "2018-06-08T10:34:56+08:00";
request.attach = "自定义数据";
request.notifyUrl = " https://www.weixin.qq.com/wxpay/pay.php";
request.goodsTag = "WXG";
request.settleInfo = new PartnerSettleInfo();
request.settleInfo.profitSharing = true;
request.supportFapiao = true;
request.amount = new CommonAmountInfo();
request.amount.total = 100L;
request.amount.currency = "CNY";
request.payer = new PartnerJsapiReqPayerInfo();
request.payer.spOpenid = "oUpF8uMuAJO_M2pxb1Q9zNjWeS6o";
request.payer.subOpenid = "oUpF8uMuAJO_M2pxb1Q9zNjWeS6o";
request.detail = new CouponInfo();
request.detail.costPrice = 608800L;
request.detail.invoiceId = "微信123";
request.detail.goodsDetail = new ArrayList<>();
{
GoodsDetail goodsDetailItem0 = new GoodsDetail();
goodsDetailItem0.merchantGoodsId = "1246464644";
goodsDetailItem0.wechatpayGoodsId = "1001";
goodsDetailItem0.goodsName = "iPhoneX 256G";
goodsDetailItem0.quantity = 1L;
goodsDetailItem0.unitPrice = 528800L;
request.detail.goodsDetail.add(goodsDetailItem0);
};
request.sceneInfo = new CommonSceneInfo();
request.sceneInfo.payerClientIp = "14.23.150.211";
request.sceneInfo.deviceId = "013467007045764";
request.sceneInfo.storeInfo = new StoreInfo();
request.sceneInfo.storeInfo.id = "0001";
request.sceneInfo.storeInfo.name = "腾讯大厦分店";
request.sceneInfo.storeInfo.areaCode = "440305";
request.sceneInfo.storeInfo.address = "广东省深圳市南山区科技中一道10000号";
try {
PartnerAPIv3PartnerJsapiPrepayResponse response = client.run(request);
// TODO: 请求成功,继续业务逻辑
System.out.println(response);
} catch (WXPayUtility.ApiException e) {
// TODO: 请求失败,根据状态码执行不同的逻辑
e.printStackTrace();
}
}
public PartnerAPIv3PartnerJsapiPrepayResponse run(PartnerAPIv3PartnerJsapiPrepayRequest request) {
String uri = PATH;
String reqBody = WXPayUtility.toJson(request);
Request.Builder reqBuilder = new Request.Builder().url(HOST + uri);
reqBuilder.addHeader("Accept", "application/json");
reqBuilder.addHeader("Wechatpay-Serial", wechatPayPublicKeyId);
reqBuilder.addHeader("Authorization", WXPayUtility.buildAuthorization(mchid, certificateSerialNo,privateKey, METHOD, uri, reqBody));
reqBuilder.addHeader("Content-Type", "application/json");
RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), reqBody);
reqBuilder.method(METHOD, requestBody);
Request httpRequest = reqBuilder.build();
// 发送HTTP请求
OkHttpClient client = new OkHttpClient.Builder().build();
try (Response httpResponse = client.newCall(httpRequest).execute()) {
String respBody = WXPayUtility.extractBody(httpResponse);
if (httpResponse.code() >= 200 && httpResponse.code() < 300) {
// 2XX 成功,验证应答签名
WXPayUtility.validateResponse(this.wechatPayPublicKeyId, this.wechatPayPublicKey,
httpResponse.headers(), respBody);
// 从HTTP应答报文构建返回数据
return WXPayUtility.fromJson(respBody, PartnerAPIv3PartnerJsapiPrepayResponse.class);
} else {
throw new WXPayUtility.ApiException(httpResponse.code(), respBody, httpResponse.headers());
}
} catch (IOException e) {
throw new UncheckedIOException("Sending request to " + uri + " failed.", e);
}
}
private final String mchid;
private final String certificateSerialNo;
private final PrivateKey privateKey;
private final String wechatPayPublicKeyId;
private final PublicKey wechatPayPublicKey;
public PartnerJsapiPrepay(String mchid, String certificateSerialNo, String privateKeyFilePath, String wechatPayPublicKeyId, String wechatPayPublicKeyFilePath) {
this.mchid = mchid;
this.certificateSerialNo = certificateSerialNo;
this.privateKey = WXPayUtility.loadPrivateKeyFromPath(privateKeyFilePath);
this.wechatPayPublicKeyId = wechatPayPublicKeyId;
this.wechatPayPublicKey = WXPayUtility.loadPublicKeyFromPath(wechatPayPublicKeyFilePath);
}
public static class PartnerAPIv3PartnerJsapiPrepayRequest {
@SerializedName("sp_appid")
public String spAppid;
@SerializedName("sp_mchid")
public String spMchid;
@SerializedName("sub_appid")
public String subAppid;
@SerializedName("sub_mchid")
public String subMchid;
@SerializedName("description")
public String description;
@SerializedName("out_trade_no")
public String outTradeNo;
@SerializedName("time_expire")
public String timeExpire;
@SerializedName("attach")
public String attach;
@SerializedName("notify_url")
public String notifyUrl;
@SerializedName("goods_tag")
public String goodsTag;
@SerializedName("settle_info")
public PartnerSettleInfo settleInfo;
@SerializedName("support_fapiao")
public Boolean supportFapiao;
@SerializedName("amount")
public CommonAmountInfo amount;
@SerializedName("payer")
public PartnerJsapiReqPayerInfo payer;
@SerializedName("detail")
public CouponInfo detail;
@SerializedName("scene_info")
public CommonSceneInfo sceneInfo;
}
public static class PartnerAPIv3PartnerJsapiPrepayResponse {
@SerializedName("prepay_id")
public String prepayId;
}
public static class PartnerSettleInfo {
@SerializedName("profit_sharing")
public Boolean profitSharing;
}
public static class CommonAmountInfo {
@SerializedName("total")
public Long total;
@SerializedName("currency")
public String currency;
}
public static class PartnerJsapiReqPayerInfo {
@SerializedName("sp_openid")
public String spOpenid;
@SerializedName("sub_openid")
public String subOpenid;
}
public static class CouponInfo {
@SerializedName("cost_price")
public Long costPrice;
@SerializedName("invoice_id")
public String invoiceId;
@SerializedName("goods_detail")
public List<GoodsDetail> goodsDetail;
}
public static class CommonSceneInfo {
@SerializedName("payer_client_ip")
public String payerClientIp;
@SerializedName("device_id")
public String deviceId;
@SerializedName("store_info")
public StoreInfo storeInfo;
}
public static class GoodsDetail {
@SerializedName("merchant_goods_id")
public String merchantGoodsId;
@SerializedName("wechatpay_goods_id")
public String wechatpayGoodsId;
@SerializedName("goods_name")
public String goodsName;
@SerializedName("quantity")
public Long quantity;
@SerializedName("unit_price")
public Long unitPrice;
}
public static class StoreInfo {
@SerializedName("id")
public String id;
@SerializedName("name")
public String name;
@SerializedName("area_code")
public String areaCode;
@SerializedName("address")
public String address;
}
}