自定义支付集成

本文档说明 Monetization 如何为开箱即用不支持的第三方支付提供商启用支付处理支持,或者在你决定通过自己的集成流程在 Monetization 之外处理支付处理逻辑时如何提供支持。

本文档主题:

Monetization 中的第三方支付处理

第三方支付处理可以通过两种方法实现:同步和异步。同步方法要求你的支付集成组件立即响应,而异步方法则先从 Monetization 提取发票,再在之后导入付款。

异步支付处理

对于异步支付处理,你从 Monetization 导出发票,付款完全在 Monetization 之外处理。获得支付处理结果后,你可以通过 CSV 文件或 Monetization API 导入这些结果。

导出发票

你可以通过配置发票导出映射器并计划导出作业,从 Monetization 导出发票,该作业会将文件导出到 SFTP 位置;也可以订阅通过 Webhook 创建发票的事件,每当创建新发票时,该事件都会向提供的 URL 地址触发一次发票请求。

导出作业 - CSV 文件到 SFTP

要将发票导出为 CSV 文件,需要配置 Invoice Export 映射器,以便将发票参数映射到 CSV 文件列。Monetization User Interface 可在 Business configuration Export Invoice mappers 下进行此类配置。

发票导出映射器配置示例 图 1: 发票导出映射器配置示例

发票导出通过 Exporting Jobs 计划执行,可以是一次性任务,也可以自动按特定周期运行。Exporting Job 会将导出的 CSV 文件保存到相应的 SFTP 位置 storage/invoice/folder_name/file_name.csv

发票导出作业示例 图 2: 发票导出作业示例

通知 - webhook 方法

通过 webhook 导出发票可让你在发票创建后立即接收发票。这通过配置 Invoice Notification Rule 实现,该规则会将每张已创建的发票作为 JSON 正文请求发送到提供的 URL 地址,并同时包含任何预先配置的标头选项。

发票创建 webhook 配置示例 图 3: 发票创建 webhook 配置示例

导入付款

你可以通过配置付款导入映射器并将付款 CSV 文件上传到 SFTP 输入位置,或者使用 Monetizations REST API,将支付交易导入 Monetization

通过 SFTP 导入 CSV 文件

要让 Monetization 通过 CSV 文件导入支付交易,必须配置 Payment Import Mapper。可通过 Monetization User Interface 在 Business configuration Import Payment mappers 下完成配置。

Payment mapper 支持将 CSV 列映射到支付交易参数,并定义文件前缀;上传的文件中必须包含该前缀。

文件会上传到 SFTP 服务器的 edl/input 文件夹,并根据处理结果移动到 edl/processededl/successfuledl/erroredl/rejected 文件夹。

付款导入映射器配置示例 图 4: 付款导入映射器配置示例

通过 API 调用导入

要通过 Monetization API 导入支付交易,请向 Monetization REST API 发送包含交易详情的 JSON 请求。

身份验证

Monetization API 使用 Bearer Token 身份验证:

  1. 使用用户名、密码和特定站点代码执行身份验证请求。
  2. 从响应中获取 token
  3. 在后续请求中将 Authorization 标头设置为 Bearer <token>
  4. 令牌将在 5 分钟后过期。
URL: {{api_url}}/authenticate

Headers
Content-Type:application/json

Body
{
    "username": "your_monetization_username",
    "password": "password",
    "site_code": "your_monetization_site_code - subdomain"
}
付款导入请求
URL: {{api_url}}/api/v1/import

Headers
Content-Type:application/json
Authorization:Bearer {{auth_token}}
Data-Type:Payment

Body
{
    "invoice_id": 123,
    "transaction_identifier": "T-1233-cew3-445f-feew3",
    "amount": 150,
    "transaction_time": 1600613169000,
    "currency": "EUR",
    "method": "other",
    "type": "charge",
    "provider": "stripe"
}

同步支付处理

同步支付处理要求 Monetization 与你的支付集成组件之间进行同步通信。这种处理方法支持信用卡/借记卡授权和即时付款。

你需要配置 Monetization,指定支付处理相关请求应发送到哪里;Monetization 也预定义了它期望收到的响应。此处理方法支持在客户上存储支付方式引用,并支持自动化收款流程。

对于 Monetization,该集成流程实际上与和现有提供商(Stripe、Braintree 等)的开箱即用集成相同。不过,通信会通过你开发的组件执行,该组件充当通往本地支付提供商的网关。

支持同步支付处理所需的基本操作:

  • Setup Intent
  • Authorize
  • Capture
  • Charge

第三方支付提供商设置

要设置第三方支付提供商集成,请配置第三方支付网关配置文件,并提供 Monetization 应向其发送请求的 URL。

这可以在 UI 中通过 System configuration Payment gateways 实现,也可以通过 Monetization REST API 创建 Payment Gateway Profile。

URL: {{api_url}}/api/v1/payment-gateway-profiles

Headers
Content-Type:application/json
Authorization:Bearer {{auth_token}}

Request
{
    "provider": "third-party",
    "headers": {
        "PGW_URL": "URL to your payment gateway"
    }
}

客户操作

客户操作仅适用于第三方支付提供商支持客户管理的情况。如果支付提供商不支持客户管理,则可将客户 ids 替换为任意值(例如,请求的 Unix 时间戳)。

创建客户(无卡)

在支付提供商服务上以对象形式创建客户。

Monetization 发送的请求:

{
    "action": "create_customer",
    "content": {
        "customer": {
            "first_name": "John",
            "last_name": "Anderson",
            "company": "Company",
            "email": "john_anderson@testmail123.com",
            "phone": "003861234335",
            "tax_identifier": "123543569596"
        },
        "billing_address": {
            "first_name": "John",
            "last_name": "Anderson",
            "company": "Company",
            "street_address": "Address street 12",
            "locality": "Name of City",
            "postal_code": "84116",
            "region": "Region",
            "country_code": "SI",
            "country_name": "Slovenia "
        }
    }
}

预期响应:

HTTP Status: 201 Created

{
    "customer": {
        "id": "payment_provider_customer_id"
    }
}

更新客户

更新支付提供商服务上的客户对象。

Monetization 发送的请求:

{
    "action": "update_customer",
    "content": {
        "customer": {
            "id": "payment_provider_customer_id_1",
            "first_name": "John",
            "last_name": "Anderson",
            "company": "Company",
            "email": "john_anderson@testmail123.com",
            "phone": "003861234335",
            "tax_identifier": "123543569596"
        },
        "billing_address": {
            "first_name": "John",
            "last_name": "Anderson",
            "company": "Company",
            "street_address": "Address street 12",
            "locality": "Name of City",
            "postal_code": "84116",
            "region": "Region",
            "country_code": "SI",
            "country_name": "Slovenia "
        }
    }
}

预期响应:

HTTP Status: 204 No Content

No Response Body

读取客户

从支付提供商服务读取客户对象。

{
    "action": "read_customer",
    "content": {
        "id": "payment_provider_customer_id_1"
    }
}

预期响应:

HTPP Status: 200 OK

{
    "content": {
        "customer": {
            "id": "payment_provider_customer_id_1",
            "first_name": "John",
            "last_name": "Anderson",
            "company": "Company",
            "email": "john_anderson@testmail123.com",
            "phone": "003861234335",
            "tax_identifier": "123543569596"
        },
        "billing_address": {
            "first_name": "John",
            "last_name": "Anderson",
            "company": "Company",
            "street_address": "Address street 12",
            "locality": "Name of City",
            "postal_code": "84116",
            "region": "Region",
            "country_code": "SI",
            "country_name": "Slovenia "
        },
        "credit_cards": [
            {
                "is_default": true,
                "card_holder_name": "John Anderson",
                "expiration_month": "03",
                "expiration_year": "2026",
                "type": "Mastercard",
                "token": "payment_provider_card_token",
                "last_four": "1234"
            }
        ]
    }
}

删除客户

从支付提供商服务删除客户对象。

Monetization 发送的请求:

{
    "action": "delete_customer",
    "content": {
        "id": "payment_provider_customer_id_1"
    }
}

预期响应:

HTTP Status: 204 No Content

No Response Body

银行卡操作

银行卡操作指设置信用卡和借记卡,或移除它们。

设置(设置银行卡请求)

触发一个流程,让客户可以提供信用卡详细信息,这些信息会被令牌化并存储在 Monetization 中。在请求添加新信用卡时,Monetization 会向你的集成组件发送设置请求。

你的集成组件需要处理与支付提供商服务相关的任何逻辑,并向 Monetization 返回重定向 URL 作为响应。随后客户会被重定向到提供的 URL,你的支付提供商托管表单将在该 URL 收集客户的银行卡详细信息并将其令牌化。

信用卡设置 图 5: 信用卡设置

Monetization 发送的请求:

{
    "action": "setup",
    "content": {
        "customer": {
            "id": "payment_provider_customer_id_1",
            "first_name": "John",
            "last_name": "Anderson",
            "company": "Company",
            "email": "john_anderson@testmail123.com",
            "phone": "003861234335",
            "tax_identifier": "123543569596"
        },
        "billing_address": {
            "first_name": "John",
            "last_name": "Anderson",
            "company": "Company",
            "street_address": "Address street 12",
            "locality": "Name of City",
            "postal_code": "84116",
            "region": "Region",
            "country_code": "SI",
            "country_name": "Slovenia "
        }
        "custom_attributes": {
            "callback_url": "https://callbackurl.com"
        }
    }
}

预期响应:

HTTP Status: 201 Created

{
    "customer": {
        "id": "payment_provider_customer_id"
    },
    "redirect_url": "https://card-data-collection-form.com"
}

删除银行卡

向你的集成组件发送请求,以便通过支付提供商服务处理信用卡引用移除逻辑;成功后,再从 Monetization 中移除该引用。

Monetization 发送的请求:

{
    "action": "delete_credit_card",
    "content": {
        "customer": {
            "id": "provider_customer_id_34"
        },
        "credit_card": {
            "token": "provider_card_token_x23423532"
        }
    }
}

预期响应:

HTTP Status: 204 No Content

No Response Body

交易操作

交易操作指对已存储支付方式(信用卡/借记卡)令牌执行的交易动作。这些动作包括:

授权

授权用于在客户的支付方式上授权(锁定)资金。授权之后可被捕获或作废。下面的请求会发送到你的集成组件,该组件应处理支付提供商服务逻辑并返回响应。

Monetization 发送的请求:

{
    "action": "authorize",
    "content": {
        "amount": 20.5,
        "currency": "EUR",
        "customer": {
            "id": "provider_customer_id_34"
        },
        "credit_card": {
            "token": "provider_card_token_x23423532"
        }
    }
}

预期响应:

HTTP Status: 202 Accepted

{
    "transaction_id": "payment_provider_transaction_id",
    "amount": 25.5,
    "currency": "EUR",
    "time": "1650629967000",
    "success": true,
    "message": "Message from provider if given",
    "code": "Code from provider if given"
}

捕获

捕获指从先前的授权请求中收取已授权资金。收取金额可以等于或低于授权金额。

任何未收取的已授权资金都将由支付提供商服务释放回客户。下面的请求会发送到你的集成组件,该组件应处理支付提供商服务逻辑并返回响应。

Monetization 发送的请求:

{
    "action": "capture",
    "content": {
        "transaction_id": "provider_transaction_id_t2134234",
        "amount": 10.5
    }
}

预期响应:

HTTP Status: 202 Accepted

{
    "transaction_id": "payment_provider_transaction_id",
    "amount": 10.5,
    "currency": "EUR",
    "time": "1650629967000",
    "success": true,
    "message": "Message from provider if given",
    "code": "Code from provider if given"
}

扣款

扣款会将授权和捕获作为单个即时交易完成。下面的请求会发送到你的集成组件,该组件应处理支付提供商服务逻辑并返回响应。

Monetization 发送的请求:

{
    "action": "charge",
    "content": {
        "amount": 25.5,
        "currency": "EUR",
        "customer": {
            "id": "provider_customer_id_34"
        },
        "credit_card": {
            "token": "provider_card_token_x23423532"
        }
    }
}

预期响应:

HTTP Status: 202 Accepted

{
    "transaction_id": "payment_provider_transaction_id",
    "amount": 25.5,
    "currency": "EUR",
    "time": "1650629967000",
    "success": true,
    "message": "Message from provider if given",
    "code": "Code from provider if given"
}

作废

作废操作会作废一笔授权交易,并释放已授权资金。下面的请求会发送到你的集成组件,该组件应处理支付提供商服务逻辑并返回响应。

Monetization 发送的请求:

{
    "action": "void",
    "content": {
        "transaction_id": "provider_transaction_id_t2134234"
    }
}

预期响应:

HTTP Status: 202 Accepted

{
    "transaction_id": "payment_provider_transaction_id",
    "time": "1650629967000",
    "success": true,
    "message": "Message from provider if given",
    "code": "Code from provider if given"
}

退款

退款会将资金退还给客户,并引用先前的扣款或捕获交易。下面的请求会发送到你的集成组件,该组件应处理支付提供商服务逻辑并返回响应。

Monetization 发送的请求:

{
    "action": "refund",
    "content": {
        "transaction_id": "provider_transaction_id_t2134234",
        "amount": 10.5
    }
}

预期响应:

HTTP Status: 202 Accepted

{
    "transaction_id": "payment_provider_transaction_id",
    "amount": 25.5,
    "currency": "EUR",
    "time": "1650629967000",
    "success": true,
    "message": "Message from provider if given",
    "code": "Code from provider if given"
}

错误处理

如果你的集成组件上的某个操作未成功,请返回 200-300 范围之外的任何状态,并在响应正文中返回错误消息。