You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP调用Swish Payout API返回PA01错误解决方案求助

问题排查及修复方案

核心问题点

  • instructionDate字段格式错误:直接传入Carbon对象,未序列化为Swish要求的ISO 8601格式字符串
  • 签名逻辑错误:
    • 重复计算哈希:openssl_sign本身支持直接指定摘要算法,不需要提前对payload做hash
    • 未指定签名算法:默认使用SHA1,不符合Swish要求的SHA512算法
    • payload序列化不一致:签名用的payload序列化结果必须和最终请求体中payload的序列化结果完全一致,需要固定json_encode参数避免格式差异
  • 测试用payeeSSN不符合要求:瑞典SSN有固定格式要求,测试时可使用官方指定的测试值

修复后的代码

// 1. 修正payload字段格式
$payload = [
    "payoutInstructionUUID" => "E4D773858AF5459B96ABCA4B9DBFF94D",
    "payerPaymentReference" => "payerRef",
    "payerAlias" => "1231388446",
    "payeeAlias" => "46712345678",
    "payeeSSN" => "191212121212", // 官方测试用合法瑞典SSN
    "amount" => "100.00",
    "currency" => "SEK",
    "payoutType" => "PAYOUT",
    "message" => "Message to the recipient.",
    // 修正为标准ISO 8601格式
    "instructionDate" => Carbon::now()->toIso8601String(),
    "signingCertificateSerialNumber" => "667A2C6E068B76988AB657351F5AF636"
];

// 固定json_encode参数,保证签名和请求的payload序列化完全一致
$jsonPayload = json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);

$pkey = openssl_pkey_get_private(file_get_contents('Swish_Merchant_TestSigningCertificate_1234679304.key'), 'swish');
// 直接对原始payload json字符串签名,指定SHA512算法,不需要提前hash
$signature = openssl_sign($jsonPayload, $signatureRaw, $pkey, OPENSSL_ALGO_SHA512) ? base64_encode($signatureRaw) : null;

$request = [
    "payload" => $payload,
    "callbackUrl" => "https://postb.in/1634560192746-3820346647407",
    "signature" => $signature
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://mss.cpc.getswish.net/swish-cpcapi/api/v1/payouts');
curl_setopt($ch, CURLOPT_PORT, 443);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_SSLCERT, 'Swish_Merchant_TestCertificate_1234679304.p12');
curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'P12');
curl_setopt($ch, CURLOPT_SSLCERTPASSWD, 'swish');
curl_setopt($ch, CURLOPT_SSLKEY, 'Swish_Merchant_TestCertificate_1234679304.key');
curl_setopt($ch, CURLOPT_SSLKEYPASSWD, 'swish');
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
curl_setopt($ch, CURLOPT_CAINFO, 'Swish_TLS_RootCA.pem');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); // 生产环境必须开启校验
curl_setopt($ch, CURLOPT_SSLVERSION, 6);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 

curl_setopt($ch, CURLOPT_POST, 1);
// 请求序列化时也用同样的json_encode参数保证一致性
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($request, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE));
$f = tmpfile();
curl_setopt($ch, CURLOPT_STDERR, $f);
$results = curl_exec($ch);

fseek($f, 0);
echo "Verbose information:\n<pre>", fread($f, 32 * 1024), "</pre>\n";
fclose($f);

$info = curl_errno($ch)>0 ? array("curl_error_".curl_errno($ch)=>curl_error($ch)) : curl_getinfo($ch);
print_r($info);
print_r($results);

curl_close($ch);

补充校验点

如果修改后仍报错,可先打印$jsonPayload和最终请求体的payload部分,确认两边结构完全一致,另外检查signingCertificateSerialNumber是否和实际使用的签名证书序列号完全匹配。

内容的提问来源于stack exchange,提问作者Phanteon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 07:54:02