@@ -81,6 +81,19 @@ public static class JsapiResult implements Serializable {
8181 private String packageValue ;
8282 private String signType ;
8383 private String paySign ;
84+ /**
85+ * <pre>
86+ * 字段名:预支付交易会话标识
87+ * 变量名:prepay_id
88+ * 是否必填:否(用户可选存储)
89+ * 类型:string[1,64]
90+ * 描述:
91+ * 预支付交易会话标识。用于后续接口调用中使用,该值有效期为2小时
92+ * 此字段用于支持用户存储prepay_id,以便复用和重新生成支付签名
93+ * 示例值:wx201410272009395522657a690389285100
94+ * </pre>
95+ */
96+ private String prepayId ;
8497
8598 private String getSignStr () {
8699 return String .format ("%s\n %s\n %s\n %s\n " , appId , timeStamp , nonceStr , packageValue );
@@ -113,6 +126,7 @@ public <T> T getPayInfo(TradeTypeEnum tradeType, String appId, String mchId, Pri
113126 JsapiResult jsapiResult = new JsapiResult ();
114127 jsapiResult .setAppId (appId ).setTimeStamp (timestamp )
115128 .setPackageValue ("prepay_id=" + this .prepayId ).setNonceStr (nonceStr )
129+ .setPrepayId (this .prepayId )
116130 //签名类型,默认为RSA,仅支持RSA。
117131 .setSignType ("RSA" ).setPaySign (SignUtils .sign (jsapiResult .getSignStr (), privateKey ));
118132 return (T ) jsapiResult ;
@@ -132,4 +146,79 @@ public <T> T getPayInfo(TradeTypeEnum tradeType, String appId, String mchId, Pri
132146 throw new WxRuntimeException ("不支持的支付类型" );
133147 }
134148 }
149+
150+ /**
151+ * <pre>
152+ * 根据已有的prepay_id生成JSAPI支付所需的参数对象(解耦版本)
153+ * 应用场景:
154+ * 1. 用户已经通过createPartnerOrderV3或unifiedPartnerOrderV3获取了prepay_id
155+ * 2. 用户希望存储prepay_id用于后续复用
156+ * 3. 支付失败后,使用存储的prepay_id重新生成支付签名信息
157+ *
158+ * 使用示例:
159+ * // 步骤1:创建订单并获取prepay_id
160+ * WxPayUnifiedOrderV3Result result = wxPayService.unifiedPartnerOrderV3(TradeTypeEnum.JSAPI, request);
161+ * String prepayId = result.getPrepayId();
162+ * // 存储prepayId到数据库...
163+ *
164+ * // 步骤2:需要支付时,使用存储的prepay_id生成支付信息
165+ * WxPayUnifiedOrderV3Result.JsapiResult payInfo = WxPayUnifiedOrderV3Result.getJsapiPayInfo(
166+ * prepayId, appId, wxPayService.getConfig().getPrivateKey()
167+ * );
168+ * </pre>
169+ *
170+ * @param prepayId 预支付交易会话标识
171+ * @param appId 应用ID
172+ * @param privateKey 商户私钥,用于签名
173+ * @return JSAPI支付所需的参数对象
174+ */
175+ public static JsapiResult getJsapiPayInfo (String prepayId , String appId , PrivateKey privateKey ) {
176+ String timestamp = String .valueOf (System .currentTimeMillis () / 1000 );
177+ String nonceStr = SignUtils .genRandomStr ();
178+ JsapiResult jsapiResult = new JsapiResult ();
179+ jsapiResult .setAppId (appId ).setTimeStamp (timestamp )
180+ .setPackageValue ("prepay_id=" + prepayId ).setNonceStr (nonceStr )
181+ .setPrepayId (prepayId )
182+ //签名类型,默认为RSA,仅支持RSA。
183+ .setSignType ("RSA" ).setPaySign (SignUtils .sign (jsapiResult .getSignStr (), privateKey ));
184+ return jsapiResult ;
185+ }
186+
187+ /**
188+ * <pre>
189+ * 根据已有的prepay_id生成APP支付所需的参数对象(解耦版本)
190+ * 应用场景:
191+ * 1. 用户已经通过createPartnerOrderV3或unifiedPartnerOrderV3获取了prepay_id
192+ * 2. 用户希望存储prepay_id用于后续复用
193+ * 3. 支付失败后,使用存储的prepay_id重新生成支付签名信息
194+ *
195+ * 使用示例:
196+ * // 步骤1:创建订单并获取prepay_id
197+ * WxPayUnifiedOrderV3Result result = wxPayService.unifiedPartnerOrderV3(TradeTypeEnum.APP, request);
198+ * String prepayId = result.getPrepayId();
199+ * // 存储prepayId到数据库...
200+ *
201+ * // 步骤2:需要支付时,使用存储的prepay_id生成支付信息
202+ * WxPayUnifiedOrderV3Result.AppResult payInfo = WxPayUnifiedOrderV3Result.getAppPayInfo(
203+ * prepayId, appId, mchId, wxPayService.getConfig().getPrivateKey()
204+ * );
205+ * </pre>
206+ *
207+ * @param prepayId 预支付交易会话标识
208+ * @param appId 应用ID
209+ * @param mchId 商户号
210+ * @param privateKey 商户私钥,用于签名
211+ * @return APP支付所需的参数对象
212+ */
213+ public static AppResult getAppPayInfo (String prepayId , String appId , String mchId , PrivateKey privateKey ) {
214+ String timestamp = String .valueOf (System .currentTimeMillis () / 1000 );
215+ String nonceStr = SignUtils .genRandomStr ();
216+ AppResult appResult = new AppResult ();
217+ appResult .setAppid (appId ).setPrepayId (prepayId ).setPartnerId (mchId )
218+ .setNoncestr (nonceStr ).setTimestamp (timestamp )
219+ //暂填写固定值Sign=WXPay
220+ .setPackageValue ("Sign=WXPay" )
221+ .setSign (SignUtils .sign (appResult .getSignStr (), privateKey ));
222+ return appResult ;
223+ }
135224}
0 commit comments