# 接口参数签名流程
# 内容
| 参数名 | 是否必填 | 类型 | 长度 | 示例 | 说明 |
|---|---|---|---|---|---|
| appId | 是 | string | - | 45eebd745dcf0b5f6d6f9fcde28cd9fe8116a892 | 应用 id (Swifood 提供) |
| storeKey | 是 | string | 100 | CVIEIYUNHTS0 | 店铺标识 (Swifood 提供) |
| param | 是 | string | - | - | 请求参数字符串 |
| sign | 是 | string | - | param 的RSA签名 |
# 示例
{
"appId": "45eebd745dcf0b5f6d6f9fcde28cd9fe8116a892",
"storeKey": "CVIEIYUNHTS0",
"sign": "abcdef",
"param": "{}"
}
# 说明
appId是由 Swifood 提供的固定值;- 根据具体接口文档,构造请求参数,将请求参数格式化为 JSON 格式,作为
param的值; - 使用 RSA 私钥对
param进行签名,得到的值作为sign的值。
# 附录 RSA 使用示例(Java 语言)
生成RSA密钥对:
import java.security.*;
import java.util.Base64;
public class RsaGenerateKeyPair {
public static void main(String[] args) throws NoSuchAlgorithmException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
KeyPair keyPair = keyPairGenerator.genKeyPair();
PublicKey publicKey = keyPair.getPublic();
byte[] publicKeyBytes = publicKey.getEncoded();
String publicKeyBase64 = Base64.getEncoder().encodeToString(publicKeyBytes);
System.out.println(publicKeyBase64);
PrivateKey privateKey = keyPair.getPrivate();
byte[] privateKeyBytes = privateKey.getEncoded();
String privateKeyBase64 = Base64.getEncoder().encodeToString(privateKeyBytes);
System.out.println(privateKeyBase64);
}
}
RSA 公钥请提交给 Swifood,请不要透露给任何第三方。
RSA 私钥由商户保管,请不要透露给任何人。
当商户请求 Swifood 的 Open API 时,商户使用 RSA 私钥对请求参数进行签名,PayCools 会使用商户提供的 RSA 公钥对请求中的签名进行验证。如果验证失败,PayCools 服务器会拒绝处理请求。
# 示例密钥对
RSA 公钥:
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAna4Dyz8nGJiAlc9jTGyRa+TtlZXYABTc+Xfb3T4NdDbnUO8vtNLHugwmqARp8kzEzsMRbmvKro4EpaXqANn7SAGo+YI6sVUDmX7ESk3P6j51PtTvWR6dikJN6qwtmV64ojEbxDnIBL3VKuctefL8uPcI7MZBUPBXg9l8CZmnn2cKqWjZ8MuEQr4G45IqmJ0tRsRmW9ofNnvI1MLPt7c/Z/D1E6HKVwjPcMZKMuF0HpIDqdQaPX83dlSzv9FF9jFR8HWfWW8Oz3jz+GtSLSdh2ERcyO56WHpWl1POV4o9jF+4R/oBgcH+0zA1Z2aFfQf/n9miMhacrioStBaHkh1f/QIDAQAB
RSA 私钥:
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCdrgPLPycYmICVz2NMbJFr5O2VldgAFNz5d9vdPg10NudQ7y+00se6DCaoBGnyTMTOwxFua8qujgSlpeoA2ftIAaj5gjqxVQOZfsRKTc/qPnU+1O9ZHp2KQk3qrC2ZXriiMRvEOcgEvdUq5y158vy49wjsxkFQ8FeD2XwJmaefZwqpaNnwy4RCvgbjkiqYnS1GxGZb2h82e8jUws+3tz9n8PUTocpXCM9wxkoy4XQekgOp1Bo9fzd2VLO/0UX2MVHwdZ9Zbw7PePP4a1ItJ2HYRFzI7npYelaXU85Xij2MX7hH+gGBwf7TMDVnZoV9B/+f2aIyFpyuKhK0FoeSHV/9AgMBAAECggEAYyqq5iucqgJXdGCO4eSx/LpolZg81ahJZXf1RgqdqYZSKnuTdFTQGflEYo0MGMAhUqwqDVkrimZ1E7zqE4kEWT/6BpnZ0edWsTWhu91+MqL/V/nRYio4CFk06a9JqliBJDhgbyOr4ReGtknYNwcT3Dw5V7hEIeRWFe007lC9tCi7mlpzBNwEIf4itmnncuA70GlxcoMkoGzfYg79eUCfXorbfJcaamR2wXLSU6KoJ422UR3L0rgzmgXzVQw9rrlQ3h6viDykKfaPi/43MN2qb6Zu5isbJIzyz0kHrcE6KJMgJhBDkLIo0f0qE/rEl1Xp/qDwr4+3WBfCHeuTFsud/QKBgQDXmA3f0/ONPMgEGdJlwG20W+7jXHabnRPuUJyDQKbtP+vuaKrpzN+jC1rlxBfAJj2iAVXXXM/RFWWapBd16TqGI4P3RW8eocaxhyl8rWSvCOy/OueNI+fM8gX/IjsJc7VMmCEWHuLvXoM2ixXPWP3v0DEPPPDrCd5dnjR6+5oGgwKBgQC7O03ps4KzMUzEtJcrFFKV0C/m1X905OqQ3cKQnGqRzLp/7d9DQsv+oKzjlpz1xktdJmig7ABiL0+FqJHdcrNiVabI5c6oS2SZkToQFlKv2GYT2KikJ0L43xLfiDvB3tues//9OXuU0WzXZqq7CNAvcmAdPjlFi9RxHsRGABo3fwKBgEi2EJ/XpQGSaUbwyoPktVsp0lS9/4aWIH20lES0DlhfwZuDk3kMzrP3hW2OiBAXFZxI5QGgXLqAg+b2xq7OvR02ZzCDK2niV9fR5Q0Wkaly0h3gqO1yGaCGU71rdwvGCXROroH+Yr0mXAyONgnbUrGJvrIL9JjgmC1syPhdWOIvAoGBAJHJbbNpWX3aB2KrE4IxwtRwVLwyxZnpnVPLuPINOVXpydZPDCc9XcYYqkZUQkeFba1MeO/Ek8/f8tWqGloKM+9/reyENFQK0Hxa/pEEMMJHh8QwUa/v+k/6sqFnXNBqjSuYEN3F4ppQL6XRhWM5S5GGR5y9lK64YGTshfvTnJZVAoGBAJ3TmJcRJWfi7CA985VAnE+IQoQfKKz9NTT7hGBwWTVd7iUc0QCpgHNIixZnfVcjKxz7Hhq6Vy+cEbDBtwbSuDfuVf1spiiqOuYVIjFqq5AsuvpX1CJmm7V+LRtJO/NXmXQP5YfojzET9NqTZvGEVXuzPA0qp8JC7HKrCYykscqE
# RSA 签名:
import java.security.KeyFactory;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
public class RsaSign {
public static final String PRIVATE_KEY = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCdrgPLPycYmICVz2NMbJFr5O2VldgAFNz5d9vdPg10NudQ7y+00se6DCaoBGnyTMTOwxFua8qujgSlpeoA2ftIAaj5gjqxVQOZfsRKTc/qPnU+1O9ZHp2KQk3qrC2ZXriiMRvEOcgEvdUq5y158vy49wjsxkFQ8FeD2XwJmaefZwqpaNnwy4RCvgbjkiqYnS1GxGZb2h82e8jUws+3tz9n8PUTocpXCM9wxkoy4XQekgOp1Bo9fzd2VLO/0UX2MVHwdZ9Zbw7PePP4a1ItJ2HYRFzI7npYelaXU85Xij2MX7hH+gGBwf7TMDVnZoV9B/+f2aIyFpyuKhK0FoeSHV/9AgMBAAECggEAYyqq5iucqgJXdGCO4eSx/LpolZg81ahJZXf1RgqdqYZSKnuTdFTQGflEYo0MGMAhUqwqDVkrimZ1E7zqE4kEWT/6BpnZ0edWsTWhu91+MqL/V/nRYio4CFk06a9JqliBJDhgbyOr4ReGtknYNwcT3Dw5V7hEIeRWFe007lC9tCi7mlpzBNwEIf4itmnncuA70GlxcoMkoGzfYg79eUCfXorbfJcaamR2wXLSU6KoJ422UR3L0rgzmgXzVQw9rrlQ3h6viDykKfaPi/43MN2qb6Zu5isbJIzyz0kHrcE6KJMgJhBDkLIo0f0qE/rEl1Xp/qDwr4+3WBfCHeuTFsud/QKBgQDXmA3f0/ONPMgEGdJlwG20W+7jXHabnRPuUJyDQKbtP+vuaKrpzN+jC1rlxBfAJj2iAVXXXM/RFWWapBd16TqGI4P3RW8eocaxhyl8rWSvCOy/OueNI+fM8gX/IjsJc7VMmCEWHuLvXoM2ixXPWP3v0DEPPPDrCd5dnjR6+5oGgwKBgQC7O03ps4KzMUzEtJcrFFKV0C/m1X905OqQ3cKQnGqRzLp/7d9DQsv+oKzjlpz1xktdJmig7ABiL0+FqJHdcrNiVabI5c6oS2SZkToQFlKv2GYT2KikJ0L43xLfiDvB3tues//9OXuU0WzXZqq7CNAvcmAdPjlFi9RxHsRGABo3fwKBgEi2EJ/XpQGSaUbwyoPktVsp0lS9/4aWIH20lES0DlhfwZuDk3kMzrP3hW2OiBAXFZxI5QGgXLqAg+b2xq7OvR02ZzCDK2niV9fR5Q0Wkaly0h3gqO1yGaCGU71rdwvGCXROroH+Yr0mXAyONgnbUrGJvrIL9JjgmC1syPhdWOIvAoGBAJHJbbNpWX3aB2KrE4IxwtRwVLwyxZnpnVPLuPINOVXpydZPDCc9XcYYqkZUQkeFba1MeO/Ek8/f8tWqGloKM+9/reyENFQK0Hxa/pEEMMJHh8QwUa/v+k/6sqFnXNBqjSuYEN3F4ppQL6XRhWM5S5GGR5y9lK64YGTshfvTnJZVAoGBAJ3TmJcRJWfi7CA985VAnE+IQoQfKKz9NTT7hGBwWTVd7iUc0QCpgHNIixZnfVcjKxz7Hhq6Vy+cEbDBtwbSuDfuVf1spiiqOuYVIjFqq5AsuvpX1CJmm7V+LRtJO/NXmXQP5YfojzET9NqTZvGEVXuzPA0qp8JC7HKrCYykscqE";
public static void main(String[] args) throws Exception {
String param = "{\n" +
" \"appId\": \"str1\",\n" +
" \"appName\": \"str2\",\n" +
" \"channelCode\": \"str3\",\n" +
" \"mchOrderId\": \"str4\",\n" +
" \"amount\": 2000,\n" +
" \"notifyUrl\": \"str5\",\n" +
" \"customerName\": \"str6\",\n" +
" \"email\": \"str7\",\n" +
" \"mobile\": \"str8\",\n" +
" \"remark\": \"str9\"\n" +
"}";
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(Base64.getDecoder().decode(PRIVATE_KEY))));
signature.update(param.getBytes());
byte[] bytes = signature.sign();
String sign = Base64.getEncoder().encodeToString(bytes);
System.out.println(sign);
}
}
sign的值:
Leh6eu60as3iiiWJiimZxZv9SKKBxyGUUoaHW0K3qZp8p4I6eyCTa4KkcZHFwE7lF16oOz5InSwDOGLAix+EMOqT8bZb/w+jzC0xGp9xdgLKEPm6woinauimyBBwvHfEydnFhrOX240XgMwMH5av9VyUIyngYslcn7PhY6zvyaQr1MYEmpkMit5m1o7iWd7sBgeXWixxCXtrKMbrG2TLepZnymk+t+nh+nR4sH66gD+uXPSq0/SzrgbChuDcdr8ybdtLOuXKX4FdM2WnvzmgSncJrU9RyRUzu6EKzCutfsYaNkV8ii70Tkabc4p4HRzaotCJ7kHyuHBPL6k0sncZrg==
# RSA 签名验证
import java.security.KeyFactory;
import java.security.Signature;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class RsaVerifySign {
public static final String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAna4Dyz8nGJiAlc9jTGyRa+TtlZXYABTc+Xfb3T4NdDbnUO8vtNLHugwmqARp8kzEzsMRbmvKro4EpaXqANn7SAGo+YI6sVUDmX7ESk3P6j51PtTvWR6dikJN6qwtmV64ojEbxDnIBL3VKuctefL8uPcI7MZBUPBXg9l8CZmnn2cKqWjZ8MuEQr4G45IqmJ0tRsRmW9ofNnvI1MLPt7c/Z/D1E6HKVwjPcMZKMuF0HpIDqdQaPX83dlSzv9FF9jFR8HWfWW8Oz3jz+GtSLSdh2ERcyO56WHpWl1POV4o9jF+4R/oBgcH+0zA1Z2aFfQf/n9miMhacrioStBaHkh1f/QIDAQAB";
public static void main(String[] args) throws Exception {
String param = "{\n" +
" \"appId\": \"str1\",\n" +
" \"appName\": \"str2\",\n" +
" \"channelCode\": \"str3\",\n" +
" \"mchOrderId\": \"str4\",\n" +
" \"amount\": 2000,\n" +
" \"notifyUrl\": \"str5\",\n" +
" \"customerName\": \"str6\",\n" +
" \"email\": \"str7\",\n" +
" \"mobile\": \"str8\",\n" +
" \"remark\": \"str9\"\n" +
"}";
String sign = "Leh6eu60as3iiiWJiimZxZv9SKKBxyGUUoaHW0K3qZp8p4I6eyCTa4KkcZHFwE7lF16oOz5InSwDOGLAix+EMOqT8bZb/w+jzC0xGp9xdgLKEPm6woinauimyBBwvHfEydnFhrOX240XgMwMH5av9VyUIyngYslcn7PhY6zvyaQr1MYEmpkMit5m1o7iWd7sBgeXWixxCXtrKMbrG2TLepZnymk+t+nh+nR4sH66gD+uXPSq0/SzrgbChuDcdr8ybdtLOuXKX4FdM2WnvzmgSncJrU9RyRUzu6EKzCutfsYaNkV8ii70Tkabc4p4HRzaotCJ7kHyuHBPL6k0sncZrg==";
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initVerify(KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(Base64.getDecoder().decode(PUBLIC_KEY))));
signature.update(param.getBytes());
boolean result = signature.verify(Base64.getDecoder().decode(sign));
System.out.println(result);
}
}
result 的值:
true
# UAT环境订单推送回调接口签名验证密钥
RSA 公钥请不要透露给任何第三方。
RSA 私钥由Swifood保管。
当 Swifood 向其他系统推送订单信息时,商户使用以上 RSA 公钥对请求参数进行签名验证,如果验证失败,商户服务器应该拒绝处理请求。
RSA 公钥:
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmkKwnkwoAGpEalUbM6TPg4ECcZBf2FYKst5gVQPrShYE6Wt4kmLsCVdHM0qoIr6TSiz0qhPwmhw898ZfzJdHPqckWka+4sUewYtxBOYC4a0Z8JYtQgTRxoK8Vvo9sXjW2pILrd0ZcB6QuHHzGC4AXjA1dB88mvsoNFi03eIhlCxFJ4fn0xA+1+359iTFymi+vTUmD6/OmphVAdTL9BYCq5NkzsoAsTmz+eF5xqkZlZ9vFhSikHN/Q/hpAW86hIs+Fq1b98ICGDRQZLrEH9E2/MB9VIzo4/U9jIf+0DPCALY8/WZJc1WXIBaDHBBVCq6xjM6JrBsF74jy01DBIP/C9wIDAQAB
API通用提示码 →