启泊支付宝对接文档

启泊支付宝对接文档


通用-微信支付

<p>通用-微信支付 线上环境地址: <a href="http://bs.qbwelink.cn/api/push/alipay">http://bs.qbwelink.cn/api/push/alipay</a> /**</p> <ul> <li>公钥加密</li> <li> </li> <li>@param publicKeyString 公钥</li> <li>@param appSecret 待加密的 appSecret</li> <li>@return 加密后的文本 */ public static String encryptByPublicKey(String publicKeyString, String appSecret ) throws Exception { X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(Base64.decodeBase64(publicKeyString)); KeyFactory keyFactory = KeyFactory.getInstance(&quot;RSA&quot;); PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec2); Cipher cipher = Cipher.getInstance(&quot;RSA&quot;); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] result = cipher.doFinal(text.getBytes()); return Base64.encodeBase64String(result); }</li> </ul> <p>简要描述 1、支付接口 请求URL <a href="http://bs.qbwelink.cn/api/push/alipay">http://bs.qbwelink.cn/api/push/alipay</a> 请求方式 POST Headers 参数名 必选 类型 说明 appId 是 string (登录平台,详见对接文档) appSecret 是 string 加密后(encryptByPublicKey) 参数 参数名 必选 类型 说明 payChannel 是 string 支付类型 【wx_pub = 微信】 money 是 string 金额 单位 元 comment 否 string 备注 minutes 是 string 续费周期 callBackUrl 是 string 回调地址 outtrxid 是 string 交易单号 startTime 是 string 缴费时间 返回示例 { “msg”: “succ”, “code”: 0, “data”: { “tradeNo”: 1554659929871224832, “payUrl”: “” } } 返回参数说明 参数名 类型 说明 tradeNo long 交易流水号 outtrxid string payUrl string 支付链接, 扫码后 调用接口, 跳转该地址 付款 简要描述 用户下单时填写的回调url</p> <p>请求方式 POST form { “data”: “{“outtrxid”:”P01202309211913175093074”,”tradeNo”:”1704816063620976640”,”trxstatus”:”0000”}”, “sign”: “aImC7Pl2gJJwgqY+2ndTwritqqReAvUUbPWVwRs+j44P9FdI4Ie9igy1GtnxIyFzA87FMdbl4z+B4qOVL9Pje+gsNqgvfS7WgRkoI5Gd60A2DwJbGnyEw4fuLRWaByNCctK2Jo0OUjUGrFnE8L6YnrOCUsv6CTQsaPzIo2N1KCQ=” }</p> <p>备注</p> <p>/**</p> <ul> <li>验证签名,指定编码</li> <li>@param content 待验证数据</li> <li>@param sign 待验证签名</li> <li>@param publicKey 公钥数据</li> <li>@param charset 编码 UTF-8</li> <li>@return 验证结果</li> <li> <p>@throws Exception 异常 */ public static boolean verifySign(String content, String sign, String publicKey, String charset) throws Exception { try { PublicKey pubKey = getPublicKeyFromX509(&quot;RSA&quot;, new ByteArrayInputStream(publicKey.getBytes())); Signature signature = Signature.getInstance(&quot;SHA1withRSA&quot;); signature.initVerify(pubKey); if (charset==null||charset.length()==0) { signature.update(content.getBytes()); } else { signature.update(content.getBytes(charset)); }</p> <pre><code>return signature.verify(Base64.decodeBase64(sign.getBytes()));</code></pre> <p>} catch (Exception var6) { throw new Exception(&quot;RSAcontent = &quot; + content + &quot;,sign=&quot; + sign + &quot;,charset = &quot; + charset, var6); } }</p> <p>/**</p> </li> <li>生成公钥</li> <li>@param algorithm 签名算法</li> <li>@param ins 公钥数据</li> <li>@return 公钥</li> <li>@throws Exception 异常 */ public static PublicKey getPublicKeyFromX509(String algorithm, InputStream ins) throws Exception { KeyFactory keyFactory = KeyFactory.getInstance(algorithm); StringWriter writer = new StringWriter(); StreamUtil.io(new InputStreamReader(ins), writer); byte[] encodedKey = writer.toString().getBytes(); encodedKey = Base64.decodeBase64(encodedKey); return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey)); }</li> </ul> <p>2.回调接口:(对接商家提供,并填入支付接口callBackUrl字段) 代码示例: package com.example.payurldemo;</p> <p>import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.example.payurldemo.utils.StreamUtil; import org.apache.commons.io.IOUtils; import org.apache.tomcat.util.codec.binary.Base64; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController;</p> <p>import java.io.; import java.security.; import java.security.spec.EncodedKeySpec; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map;</p> <p>@RestController public class CallBackController {</p> <p>private static String publicKEy = &quot;xxx&quot;;</p> <p>private static String privateKey =&quot;xxx&quot;;</p> <p>@PostMapping(&quot;/alipay/callback&quot;) public Map&lt;String,Object&gt; alipayCallback(@RequestBody AlipayCallbackRequest request) throws Exception { // 获取请求中的数据和签名 String data = request.getData(); String sign = request.getSign(); // 这里写处理微信支付回调的逻辑,验证回调数据的签名并比对 //验签 verifySign(data,sign,publicKEy,&quot;UTF-8&quot;); //TODO 处理业务逻辑</p> <pre><code>// 处理完毕后返回给微信支付的成功响应 Map&amp;lt;String,Object&amp;gt; resultMap = new HashMap&amp;lt;&amp;gt;(); resultMap.put(&amp;quot;code&amp;quot;,&amp;quot;0000&amp;quot;); resultMap.put(&amp;quot;msg&amp;quot;,&amp;quot;成功&amp;quot;); return resultMap;</code></pre> <p>}</p> <p>工具类和加验签方法如下: /**</p> <ul> <li>验证签名,指定编码</li> <li>@param content 待验证数据</li> <li>@param sign 待验证签名</li> <li>@param publicKey 公钥数据</li> <li>@param charset 编码 UTF-8</li> <li>@return 验证结果</li> <li> <p>@throws Exception 异常 */ public static boolean verifySign(String content, String sign, String publicKey, String charset) throws Exception { try { PublicKey pubKey = getPublicKeyFromX509(&quot;RSA&quot;, new ByteArrayInputStream(publicKey.getBytes())); Signature signature = Signature.getInstance(&quot;SHA1withRSA&quot;); signature.initVerify(pubKey); if (charset==null||charset.length()==0) { signature.update(content.getBytes()); } else { signature.update(content.getBytes(charset)); }</p> <pre><code>return signature.verify(Base64.decodeBase64(sign.getBytes()));</code></pre> <p>} catch (Exception var6) { throw new Exception(&quot;RSAcontent = &quot; + content + &quot;,sign=&quot; + sign + &quot;,charset = &quot; + charset, var6); } } /**</p> </li> <li>生成公钥</li> <li>@param algorithm 签名算法</li> <li>@param ins 公钥数据</li> <li>@return 公钥</li> <li>@throws Exception 异常 */ public static PublicKey getPublicKeyFromX509(String algorithm, InputStream ins) throws Exception { KeyFactory keyFactory = KeyFactory.getInstance(algorithm); StringWriter writer = new StringWriter(); StreamUtil.io(new InputStreamReader(ins), writer); byte[] encodedKey = writer.toString().getBytes(); encodedKey = Base64.decodeBase64(encodedKey); return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey)); }</li> </ul> <p>public static String sign(String content, String privateKey, String charset) throws Exception { try { PrivateKey priKey = getPrivateKeyFromPKCS8(&quot;RSA&quot;, new ByteArrayInputStream(privateKey.getBytes())); Signature signature = Signature.getInstance(&quot;SHA1withRSA&quot;); signature.initSign(priKey); if (charset == null || charset.isEmpty()) { signature.update(content.getBytes()); } else { signature.update(content.getBytes(charset)); } byte[] signed = signature.sign(); return Base64.encodeBase64String(signed); } catch (Exception var6) { throw new Exception(&quot;Failed to sign content: &quot; + content + &quot;, charset: &quot; + charset, var6); } } public static PrivateKey getPrivateKeyFromPKCS8(String algorithm, InputStream ins) throws Exception { KeyFactory keyFactory = KeyFactory.getInstance(algorithm); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int length; while ((length = ins.read(buffer)) != -1) { byteArrayOutputStream.write(buffer, 0, length); } byte[] keyBytes = byteArrayOutputStream.toByteArray(); EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(keyBytes); return keyFactory.generatePrivate(privateKeySpec); } public static String signData(String privateKeyStr, String data) throws Exception { String algorithm = &quot;SHA1withRSA&quot;; // 默认算法为SHA256withRSA</p> <pre><code>// 将私钥字符串转换为 PrivateKey 对象 byte[] privateKeyBytes = Base64.decodeBase64(privateKeyStr); KeyFactory keyFactory = KeyFactory.getInstance(&amp;quot;RSA&amp;quot;); PrivateKey privateKey = keyFactory.generatePrivate(new X509EncodedKeySpec(privateKeyBytes)); // 使用私钥进行数字签名 Signature signature = Signature.getInstance(algorithm); signature.initSign(privateKey); signature.update(data.getBytes(&amp;quot;UTF-8&amp;quot;)); byte[] signatureBytes = signature.sign(); // 将签名结果转换为字符串 return Base64.encodeBase64String(signatureBytes);</code></pre> <p>}</p> <p>/**</p> <ul> <li>对数据进行加签,指定编码</li> <li>@param privateKeyStr 私钥字符串</li> <li>@param data 待加签数据</li> <li>@param charset 编码 UTF-8</li> <li>@return 加签结果</li> <li> <p>@throws Exception 异常 */ public static String signData(String privateKeyStr, String data, String charset) throws Exception { try { PrivateKey privateKey = getPrivateKeyFromString(&quot;RSA&quot;, privateKeyStr); Signature signature = Signature.getInstance(&quot;SHA1withRSA&quot;); signature.initSign(privateKey); if (charset == null || charset.length() == 0) { signature.update(data.getBytes()); } else { signature.update(data.getBytes(charset)); }</p> <pre><code>byte[] signatureBytes = signature.sign(); return Base64.encodeBase64String(signatureBytes);</code></pre> <p>} catch (Exception e) { throw new Exception(&quot;data = &quot; + data + &quot;, privateKeyStr = &quot; + privateKeyStr + &quot;, charset = &quot; + charset, e); } }</p> </li> </ul> <p>/**</p> <ul> <li>从字符串中获取私钥</li> <li>@param algorithm 签名算法</li> <li>@param privateKeyStr 私钥字符串</li> <li>@return 私钥</li> <li>@throws Exception 异常 */ public static PrivateKey getPrivateKeyFromString(String algorithm, String privateKeyStr) throws Exception { byte[] privateKeyBytes = Base64.decodeBase64(privateKeyStr); KeyFactory keyFactory = KeyFactory.getInstance(algorithm); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes); return keyFactory.generatePrivate(keySpec); }</li> </ul> <p>}</p> <p>实体类为: package com.example.payurldemo;</p> <p>import lombok.Data;</p> <p>@Data public class AlipayCallbackRequest { private String data; private String sign;</p> <p>}</p> <p>其他io工具类 package com.example.payurldemo.utils;</p> <p>import java.io.IOException; import java.io.InputStreamReader; import java.io.StringWriter;</p> <p>复制 public class StreamUtil {</p> <p>public static void io(InputStreamReader reader, StringWriter writer) throws IOException { char[] buffer = new char[4096]; int bytesRead; while ((bytesRead = reader.read(buffer)) != -1) { writer.write(buffer, 0, bytesRead); } writer.flush(); }</p> <p>}</p>

页面列表

ITEM_HTML