Headless SDK (支付 iOS)


👍

推荐的 SDK

我们建议使用iOSSeamless SDK,以获得流畅的集成体验。该选项提供了灵活的支付解决方案,预置了用户界面组件和自定义选项。

Yuno 的 Headless iOS SDK 可让您同时创建付款和注册付款方式。请注意,使用Headless SDK 时,您需要通过 API 请求并发送支付提供商在其 API 中生成支付所需的所有必填字段。

Yuno 的Headless SDK 可让您在两种不同的情况下创建支付:

  • 使用信用卡信息或其他支付方式创建一次性使用Token,然后创建支付。
  • 创建一个 一次性使用Token 使用 vaulted_token 从先前注册的付款方式中收集欺诈提供商的相关信息,然后创建付款。

以下步骤介绍了如何使用 Yuno 的Headless SDK 创建付款。

第 1 步:在项目中加入程序库

第一步是在 iOS 项目中安装 Yuno SDK。

📘

检查 iOS SDK 版本

要查看所有可用版本,请访问 Yuno iOS SDK 软件源上的发布页面

您可以通过两种方式安装 Yuno SDK:

  • 茧足动物:如果您没有 Podfile,请按照 CocoaPods 指南创建一个 Podfile。创建 Podfile 后,在 Podfile 中添加下面一行,即可将 Yuno SDK 与 Cocoapods 集成:
    pod "YunoSDK","~> {last_version}
  • Swift 软件包管理器:设置 Swift 软件包,然后将 Yuno SDK 添加为依赖项,如下代码块所示:
    dependencies: [
        .package(url: "https://github.com/yuno-payments/yuno-sdk-ios.git", .upToNextMajor(from: "{last_version}"))
    ]

步骤 2:使用公钥Initialize Headless SDK

要initialize Headless SDK,您需要导入 Yuno 并提供一个有效的 PUBLIC_API_KEY.如果您没有 API 凭据,请访问开发人员(凭据)页面,查看如何从仪表板检索凭据

🚧

UISceneDelegate 初始化

如果您的应用程序使用 UISceneDelegate,确保将 Yuno 初始化代码放在 SceneDelegate. 了解更多

下面的代码块提供了一个导入和初始化 Yuno.

导入 YunoSDK

Yunoinitialize(
    apiKey:PUBLIC_API_KEY"
)

步骤 3:开始结账

接下来,您将使用 apiClientPayment 函数,提供必要的配置参数。客户选择付款方式后,您需要调用该函数。这样,SDK 就会开始收集相关信息,用于 3DS 和防欺诈工具。 路由.

参数

下表列出了所有必填参数及其说明。

参数说明
countryCode该参数用于确定正在配置支付流程的国家。支持的国家及其 countryCode 可在 国家覆盖范围 page.
checkout_session指使用创建结账会话 endpoint创建的当前付款的结账会话。Example: '438413b7-4921-41e4-b8f3-28a5a0141638'

下面的代码块提供了一个参数配置示例。

var apiClientPayment:YunoPaymentHeadless?

apiClientPayment = Yuno.apiClientPayment(
   countryCode:"CO"、
   checkoutSession:"438413b7-4921-41e4-b8f3-28a5a0141638"
)

步骤 4:生成token

收集完所有用户信息后,就可以开始付款了。首先,您需要使用函数 apiClientPayment.generateToken.由于这是一个异步函数,您可以使用 do/catch 以确保正确处理触发的错误。下面有两个创建一次性token的不同示例:

  1. 例 1:使用银行卡作为支付方式创建一次性token ,并包含所有必要的银行卡信息。
  2. 示例 2:使用 vaulted_token 信息。
👍

使用拱顶Token的优势

使用 SDK 的保险库token 可确保从您配置的提供商处收集所有欺诈信息,并将其附加到一次性token中。此外,如果提供商需要,您还可以加入分期付款详细信息和安全代码。

让 tokenCollectedData:令牌收集数据 = TokenCollectedData(
   checkoutSession:"438413b7-4921-41e4-b8f3-28a5a0141638",
    paymentMethod:CollectedData(
        类型"CARD"、
       vaultedToken: nil、
        card:CardData(
            save: true、
            detail:CardData.Detail(
                number: "41111111111111"、
                expirationMonth:12,
                expirationYear: 25、
                securityCode:"123",
                持有人姓名"Andrea"、
                类型:.credit
            ),
            分期付款:CardData.Installment(
                id: "64ceacef-0886-4c81-9779-b2b3029c4e8b",
                值:1
            )
        ),
        客户:客户()
    )
)

let result = try await apiClientPayment.generateToken(
    data: tokenCollectedData
)
让 tokenCollectedData:令牌收集数据 = TokenCollectedData(
   checkoutSession:"438413b7-4921-41e4-b8f3-28a5a0141638",
    paymentMethod:CollectedData(
        类型"CARD"、
       vaultedToken: "c8bb2bd8-8abf-4265-b478-0ec4e3c10cd5",
        卡CardData(
            安装:CardData.Installment(
                id: "64ceacef-0886-4c81-9779-b2b3029c4e8b",
                值:1
            )
        ),
        客户:客户()
    )
)

let result = try await apiClientPayment.generateToken(
    data: tokenCollectedData
)

下面的代码块介绍了 apiClientPayment.generateToken 函数的响应。响应是一个类型为 [String: Any].

 [token":"9ee44ac7-9134-4598-ae28-a26fec03099d",
     "类型":"卡"、
     客户["billing_address":nil、
                  "first_name": nil、
                  性别"",
                  "电话": nil、
                  "浏览器信息["color_depth": nil、
                                   语言"en"、
                                   "accept_header":"*/*",
                                   "browser_time_difference": nil、
                                   "accept_content": nil、
                                   "accept_browser": nil、
                                   "java_enabled": nil、
                                   "user_agent":"YunoSDK_Example/1 CFNetwork/1406.0.4 Darwin/22.6.0"、
                                   "screen_height":"844.0",
                                   "屏幕宽度"390.0",
                                   "javascript_enabled": nil]、
                  "document": nil、
                  "last_name":无、
                  "设备指纹":无、
                 email":无]、
     "国家":"BR"、
     "vaulted_token": nil、
     "分期付款":["利率":"",
                     "id":"cca80084-961b-4212-9c34-54f03f4f10ae",
                     "值": 24、
                     "amount": nil]、
     "card_data": nil], "card_data": nil
[token":"9ee44ac7-9134-4598-ae28-a26fec03099d",
     "类型":"卡"、
     客户["billing_address":nil、
                  "first_name": nil、
                  性别"",
                  "电话": nil、
                  "浏览器信息["color_depth": nil、
                                   语言"en"、
                                   "accept_header":"*/*",
                                   "browser_time_difference": nil、
                                   "accept_content": nil、
                                   "accept_browser": nil、
                                   "java_enabled": nil、
                                   "user_agent":"YunoSDK_Example/1 CFNetwork/1406.0.4 Darwin/22.6.0"、
                                   "screen_height":"844.0",
                                   "屏幕宽度"390.0",
                                   "javascript_enabled": nil]、
                  "document": nil、
                  "last_name":无、
                  "设备指纹":无、
                 email":无]、
     "国家":"BR"、
     "vaulted_token":"a1c7c5d1-b260-4dc6-909a-8368704233cf",
     "分期付款":["利率":"",
                     "id":"cca80084-961b-4212-9c34-54f03f4f10ae",
                     "值": 24、
                     "amount": nil]、
     "card_data": nil], "card_data": nil

第 5 步:创建付款

完成上述步骤后,就可以创建付款。必须使用 "创建付款"(Create Payment endpoint来创建背对背付款。商家应调用自己的后台,使用一次性token 和结账会话在 Yuno 中创建付款。

endpoint 响应包括 sdk_action_required 参数,该参数表示是否需要其他操作来完成付款:

对于同步支付方法,支付会立即完成。在这种情况下 sdk_action_required 在API响应中将返回false,支付流程终止。若支付流程需要SDK进一步交互才能完成, sdk_action_required 将为真;在此情况下,请继续执行步骤6的说明。

步骤 6:处理异步支付(可选)

如3DS卡验证页面所述,使用3DS付款可能需要额外的验证,以检查客户的身份。如果需要3DS验证挑战,创建支付 endpoint 响应将包含以下内容:

  • 状态等于 PENDING 和子状态等于 WAITING_ADDITIONAL_STEP
  • sdk_action_required = true
  • A redirect_url 中定义的 payment.payment_method.payment_method_detail.card

要执行挑战并完成付款,您有两个集成选项:

获取 3DS 挑战赛 URL

要获取3DS挑战URL,你需要调用 getThreeDSecureChallenge 功能,提供 checkoutSession.......。 checkoutSession 只有在不使用创建付款时才需要。下面是使用 getThreeDSecureChallenge 功能。由于 getThreeDSecureChallenge 是一个异步函数,您可以使用 do/catch 以确保正确处理触发的错误。

func getThreeDSecureChallengecheckoutSession: String?) async throws -> ThreeDSecureChallengeResponse

"(《世界人权宣言》) getThreeDSecureChallenge 函数将返回 ThreeDSecureChallengeResponse将在下一个代码块中介绍:

public struct ThreeDSecureChallengeResponse {
    public let url: String
}

"(《世界人权宣言》) url 将包含一个有效的 URL,您需要重定向客户以完成挑战。

您有责任将客户重定向到由 getThreeDSecureChallenge() 功能来完成挑战。客户成功完成 3DS 挑战后,将自动跳转到 callback_url时提供的 checkout_session创建结账会话 endpoint。

要确认挑战已完成,可以打开网络视图加载所提供的 URL 并监听 messageFromWeb 事件。下面的示例代码演示了如何监听该事件。

class HeadlessWebView: UIViewController, WKScriptMessageHandler, WKNavigationDelegate {

    private var webView: WKWebView!
    private var url: String = ""
    private let configuration = WKWebViewConfiguration()

    init(url: String) {
        self.url = url
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder: NSCoder) {
        nil
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        webViewConfig()
    }

    func webViewConfig() {
   
        configuration.preferences.javaScriptEnabled = true
        configuration.userContentController.add(self, name: "messageFromWeb")
        webView = WKWebView(frame: view.bounds, configuration: configuration)
        webView.navigationDelegate = self

        guard let url = URL(string: url) else {
            return
        }
        let request = URLRequest(url: url)
        webView.load(request)

    }

    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        if message.name == "messageFromWeb", let messageBody = message.body as? String {
            self.dismiss(animated: true)

        }
    }

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        self.configuration.userContentController.removeScriptMessageHandler(forName: "messageFromWeb")
    }

}

回复将告知质疑状态,可以是 COMPLETEDERROR.下一个代码块介绍了每种可能选项的示例。

{
   "origin":"CHALLENGE",
   "status":"COMPLETED",
   "data":"callback_url"
}
{
   "origin":"CHALLENGE",
   "status":"ERROR",
   "data":"Invalid 3DS provider"
}

要完成Headless SDK 支付流程,您需要使用Yuno Webhooks,它会及时通知您 3DS 挑战的结果和最终支付状态。使用网络钩子可确保您收到有关支付交易进度的实时更新。除网络钩子外,您还可以使用 "按 ID 检索付款"endpoint检索付款信息。

要完成支付实施并了解剩余步骤,请访问无头 SDK(支付)

步骤 7:处理付款状态(可选)

🚧

深度链接和 Mercado Pago Checkout Pro

只有在使用依赖深度链接的支付方式或 Mercado Pago Checkout Pro 时,才需要执行此步骤。如果您的付款方式不使用深度链接,您可以跳过这一步。

有些支付方法会让用户离开您的应用程序来完成交易。支付完成后,用户会通过深层链接重定向回到您的应用程序。SDK 会使用此深度链接检查发生了什么,检查支付是否成功、失败或取消,并向用户显示状态屏幕。

为此,您需要更新您的 AppDelegate 将输入的 URL 传回 Yuno SDK。这样,SDK 就能读取结果并显示支付状态。下面的代码片段展示了如何将其添加到您的应用程序中:

func application(_ app: UIApplication,
                 open url: URL,
                 options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {

  guard url.scheme == "yunoexample" else { return false }

  return Yuno.receiveDeeplink(url, showStatusView: true)
}

这段代码会侦听打开应用程序的深度链接。当收到 URL 时,它会检查该方案是否与您在 callback_url 在结账会话设置期间。如果匹配,URL 将通过以下方式传递给 Yuno SDK Yuno.receiveDeeplink(...).然后,SDK 会读取支付结果,如果 showStatusView 设置为 true,向用户显示相应的状态屏幕。

确保 url.scheme 代码中的 callback_url 时提供的 checkout_session.

📘

演示应用程序

除提供的代码示例外,您还可以访问Yuno 存储库,获取 Yuno iOS SDK 的完整实现。