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

255 lines
8.6 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/merchant/4014931831
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 JsapiPrepay {
private static String HOST = "https://api.mch.weixin.qq.com";
private static String METHOD = "POST";
private static String PATH = "/v3/pay/transactions/jsapi";
public static void main(String[] args) {
// TODO: 请准备商户开发必要参数参考https://pay.weixin.qq.com/doc/v3/merchant/4013070756
JsapiPrepay client = new JsapiPrepay(
"19xxxxxxxx", // 商户号,是由微信支付系统生成并分配给每个商户的唯一标识符,商户号获取方式参考 https://pay.weixin.qq.com/doc/v3/merchant/4013070756
"1DDE55AD98Exxxxxxxxxx", // 商户API证书序列号如何获取请参考 https://pay.weixin.qq.com/doc/v3/merchant/4013053053
"/path/to/apiclient_key.pem", // 商户API证书私钥文件路径本地文件路径
"PUB_KEY_ID_xxxxxxxxxxxxx", // 微信支付公钥ID如何获取请参考 https://pay.weixin.qq.com/doc/v3/merchant/4013038816
"/path/to/wxp_pub.pem" // 微信支付公钥文件路径,本地文件路径
);
DirectAPIv3JsapiPrepayRequest request = new DirectAPIv3JsapiPrepayRequest();
request.appid = "wxd678efh567hg6787";
request.mchid = "1230000109";
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.supportFapiao = false;
request.amount = new CommonAmountInfo();
request.amount.total = 100L;
request.amount.currency = "CNY";
request.payer = new JsapiReqPayerInfo();
request.payer.openid = "oUpF8uMuAJO_M2pxb1Q9zNjWeS6o";
request.detail = new CouponInfo();
request.detail.costPrice = 608800L;
request.detail.invoiceId = "微信123";
request.detail.goodsDetail = new ArrayList<>();
{
GoodsDetail goodsDetailItem = new GoodsDetail();
goodsDetailItem.merchantGoodsId = "1246464644";
goodsDetailItem.wechatpayGoodsId = "1001";
goodsDetailItem.goodsName = "iPhoneX 256G";
goodsDetailItem.quantity = 1L;
goodsDetailItem.unitPrice = 528800L;
request.detail.goodsDetail.add(goodsDetailItem);
};
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号";
request.settleInfo = new SettleInfo();
request.settleInfo.profitSharing = false;
try {
DirectAPIv3JsapiPrepayResponse response = client.run(request);
// TODO: 请求成功,继续业务逻辑
System.out.println(response);
} catch (WXPayUtility.ApiException e) {
// TODO: 请求失败,根据状态码执行不同的逻辑
e.printStackTrace();
}
}
public DirectAPIv3JsapiPrepayResponse run(DirectAPIv3JsapiPrepayRequest 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, DirectAPIv3JsapiPrepayResponse.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 JsapiPrepay(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 DirectAPIv3JsapiPrepayRequest {
@SerializedName("appid")
public String appid;
@SerializedName("mchid")
public String mchid;
@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("support_fapiao")
public Boolean supportFapiao;
@SerializedName("amount")
public CommonAmountInfo amount;
@SerializedName("payer")
public JsapiReqPayerInfo payer;
@SerializedName("detail")
public CouponInfo detail;
@SerializedName("scene_info")
public CommonSceneInfo sceneInfo;
@SerializedName("settle_info")
public SettleInfo settleInfo;
}
public static class DirectAPIv3JsapiPrepayResponse {
@SerializedName("prepay_id")
public String prepayId;
}
public static class CommonAmountInfo {
@SerializedName("total")
public Long total;
@SerializedName("currency")
public String currency;
}
public static class JsapiReqPayerInfo {
@SerializedName("openid")
public String openid;
}
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 SettleInfo {
@SerializedName("profit_sharing")
public Boolean profitSharing;
}
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;
}
}