尝试在NodeJS项目中实现SimplePay(OTP)支付网关,但我无法获得与技术文档中相同的签名

1cosmwyk  于 2022-12-12  发布在  Node.js
关注(0)|答案(1)|浏览(106)

我正在尝试在NodeJS项目中实现SimplePay(OTP)支付网关。
到目前为止,我只是在探索和遵循技术文档,并尝试根据文档将测试开始请求放在一起,但我无法获得与文档中预期的相同签名。
文档(示例包含在PHP SDK中):
如何创建签名:

signature = codeBase64(hmacWithSha384(merchantKey, message))

(so创建在post正文中发送的整个JSON的HMCAC SHA384哈希(这是消息),并使用merchantKey,然后对哈希结果进行base64编码)
商户密钥:

FxDa5w314kLlNseq2sKuVwaqZshZT5d6

message(应该是POST主体中发送的整个JSON):

{"salt":"c1ca1d0e9fc2323b3dda7cf145e36f5e","merchant":"PUBLICTESTHUF","orderRef":"101010516348232058105","currency":"HUF","customerEmail":"sdk_test@otpmobil.com","language":"HU","sdkVersion":"SimplePayV2.1_Payment_PHP_SDK_2.0.7_190701:dd236896400d7463677a82a47f53e36e","methods":\["CARD"\],"total":"25","timeout":"2021-10-30T12:30:11+00:00","url":"https://sdk.simplepay.hu/back.php"}

根据文件,签名的预期结果:

gcDJ8J7TyT1rC/Ygj/8CihXaLwniMWRav09QSEMQUnv5TbYaEDvQAuBE1mW3plvZ

现在我已经尝试了很多方法,但似乎都无法得到相同的签名。下面是我的代码和问题:

const bodyAsText = `{"salt":"c1ca1d0e9fc2323b3dda7cf145e36f5e","merchant":"PUBLICTESTHUF","orderRef":"101010516348232058105","currency":"HUF","customerEmail":"sdk_test@otpmobil.com","language":"HU","sdkVersion":"SimplePayV2.1_Payment_PHP_SDK_2.0.7_190701:dd236896400d7463677a82a47f53e36e","methods":\["CARD"\],"total":"25","timeout":"2021-10-30T12:30:11+00:00","url":"https://sdk.simplepay.hu/back.php"}\`;

const message = JSON.parse(bodyAsText);

const merchantKey = "FxDa5w314kLlNseq2sKuVwaqZshZT5d6";

const signature = createHmac("sha384", merchantKey)
.update(JSON.stringify(message))
.digest("base64");

console.log("Your signature is: ", signature);\

我以前也试过这种办法:

const signature = createHmac("sha384", merchantKey) .update(JSON.stringify(message)) .digest().toString('base64');

但结果是一样的:

dwvuWq4Hyec9BtriL4N+LC42u4G10PcHcpcvCM9TIxL7VJJFBvIi5jQLev86Pedu

我试过通过 Postman 提交请求。对于正文中的同一个JSON,我的签名出现签名错误,而在文档中编写的签名成功,这是意料之中的,我只是没有得到我所缺少的东西。

wbgh16ku

wbgh16ku1#

该问题是由消息中的URL以及PHP(文档中引用的)和JavaScript/NodeJS(您正在使用的)之间的差异引起的。
在PHP中,\/不被视为转义序列,而被解释为\/。在JavaScript中,\/被视为转义序列,而被解释为/。要将输入解释为\/,必须在消息字符串中将\/(或/)替换为\\/,例如:

const crypto = require('crypto');

const merchantKey = "FxDa5w314kLlNseq2sKuVwaqZshZT5d6";
const body = {"salt":"c1ca1d0e9fc2323b3dda7cf145e36f5e","merchant":"PUBLICTESTHUF","orderRef":"101010516348232058105","currency":"HUF","customerEmail":"sdk_test@otpmobil.com","language":"HU","sdkVersion":"SimplePayV2.1_Payment_PHP_SDK_2.0.7_190701:dd236896400d7463677a82a47f53e36e","methods":["CARD"],"total":"25","timeout":"2021-10-30T12:30:11+00:00","url":"https:\/\/sdk.simplepay.hu\/back.php"}
const message = JSON.stringify(body).replace(/\//g, "\\\/");

const signature = crypto.createHmac("sha384", merchantKey)
.update(message)
.digest("base64");

console.log("Your signature is: ", signature); // Your signature is:  gcDJ8J7TyT1rC/Ygj/8CihXaLwniMWRav09QSEMQUnv5TbYaEDvQAuBE1mW3plvZ

请注意,此修复是在消息字符串中进行的,而不是在JavaScript对象中进行的,其中\/将被解释为/\\/将被解释为\\/(而不是\/)。
另请注意,您为该消息发布的JavaScript对象中有两处拼写错误:必须删除两个方括号前的反斜杠。

相关问题