【问题标题】:How to encrypt payload in Python to make a payment - Adyen payment gateway如何在 Python 中加密有效负载以进行支付 - Adyen 支付网关
【发布时间】:2019-06-04 14:17:38
【问题描述】:

我对编码还很陌生,这是我正在从事的第一个更大的 Python 项目之一,我在提交 Adyen 付款时遇到了问题。

我正在尝试在使用 Adyen 支付网关的网站上进行支付。 Adyen 对您的支付数据客户端进行加密,并且只接受加密请求,否则他们将返回 400 错误请求并且付款将无法通过。

当谈到想法时,我被卡住了,我在手动付款时分析了 Charles 的流量 - 在付款之前,手机会向 Adyen 网站上的 this 链接发送 GET 请求,然后下一个请求是对已加密数据的支付 URL 的 PUT 请求。

我不知道如何加密我的详细信息,让 Adyen 接受它们并成功完成付款。 我是否在付款前使用链接中的代码在我的计算机上创建一个 JS 文件,然后我可以在我的 Python 脚本中调用 JS 来加密详细信息?

我尝试将未加密的数据发送到支付 URL,但就像我之前所说的那样,它只是返回 400 状态代码并且支付没有通过。 正确请求发送的加密数据如下所示: "encryptedData": "adyenjs_0_1_18$......"

def payment():
        payParams = {
            'api_key': 'websiteAPIKey',
            'channel': 'iphone-mosaic',
            'type': 'CARD'
        }
        payPayload = {
            'number': cardN,
            'expiryMonth': expM,
            'expiryYear': expY,
            'cvc': cvc,
            'holderName': fName + ' ' + lName
        }
        pay = s.put('websiteUsingAdyenGateway', headers = payHeaders, params = payParams, data = json.dumps(payPayload))

预期的结果应该是 200 状态码,付款实际通过但没有加密,它总是返回 400 状态码。

【问题讨论】:

标签: python encryption adyen


【解决方案1】:

我认为您正在将自己插入不应该的流程中。 Adyen 有意在客户端上为您加密详细信息。这是PCI compliancy 所必需的。

仅当您是 PCI 1 级或 2 级时才处理 raw card data。您需要每年处理 100 万次或更多交易才能获得资格。

假设不是,您应该使用一个组件(捆绑的 js 购物者收集表单的 Adyen 术语)来收集卡片详细信息。您有两个组件可供选择:

  • card component:更即插即用,为所有卡片收集字段插入一个div
  • secure fields component:更可定制,为卡片的每个字段插入一个 div(例如数字、cvc、到期)

注意:两者都要求您create an origin key 必须与您付款的域相匹配。例如如果您要进行测试并将服务器托管在 localhost 的 8080 端口上,请为 http://localhost:8080 创建一个原始密钥。

在任何一种情况下,这两种方法都需要您实现一个回调,该回调将为您提供您需要传递给 Adyen 的加密 blob。

function handleOnChange(state, component) {
    if (state.isValid){
        // All card fields pass formatting validation
        fetch('localhost:8080/handleComponentData',{
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(state.data)
        })
    }
}

state.data 可以按原样在 paymentMethod 对象中作为 /payments 请求的一部分传递

state.data 的内容:

{
    type: "scheme",
    encryptedCardNumber: "adyenjs_0_1_18$MT6ppy0FAMVMLH...",
    encryptedExpiryMonth: "adyenjs_0_1_18$MT6ppy0FAMVMLH...",
    encryptedExpiryYear: "adyenjs_0_1_18$MT6ppy0FAMVMLH...",
    encryptedSecurityCode: "adyenjs_0_1_18$MT6ppy0FAMVMLH..."
}

/支付请求:

curl https://checkout-test.adyen.com/v46/payments \
-H "x-API-key: YOUR_X-API-KEY" \
-H "content-type: application/json" \
-d '{
  "amount":{
    "currency":"EUR",
    "value":1000
  },
  "reference":"YOUR_ORDER_NUMBER",
  "paymentMethod":{
    "type":"scheme",
    "encryptedCardNumber":"adyenjs_0_1_18$MT6ppy0FAMVMLH...",
    "encryptedExpiryMonth":"adyenjs_0_1_18$MT6ppy0FAMVMLH...",
    "encryptedExpiryYear":"adyenjs_0_1_18$MT6ppy0FAMVMLH...",
    "encryptedSecurityCode":"adyenjs_0_1_18$MT6ppy0FAMVMLH..."
  },
  "returnUrl":"https://your-company.com/checkout/",
  "merchantAccount":"YOUR_MERCHANT_ACCOUNT"
}'

【讨论】:

  • 你知道是否有办法在后端进行测试吗?我正在尝试找到要传递给“paymentMethod”对象的测试数据。是否有任何测试'encryptedCardNumber'?
猜你喜欢
  • 1970-01-01
  • 2018-04-11
  • 2021-03-04
  • 2015-11-21
  • 2015-06-01
  • 2016-02-25
  • 2016-06-16
  • 1970-01-01
  • 2012-05-24
相关资源
最近更新 更多