Card-SDK-iOS
在 Tap Payments,我们致力于使您的支付变得更加简单。作为一个符合 PCI 标准的公司,我们为您提供了一站式解决方案来处理您的 iOS 应用中的卡支付。
要求
- 我们支持 iOS 13.0+
- Swift 版本 5.0+
- Objective-C
获取您的 Tap 密钥
您始终可以使用示例应用中的示例密钥,但我们建议您访问我们的注册页面。您需要注册您的 bundle id
以获取您需要的 Tap 密钥
来激活我们的 Card SDK
。
安装
我们为您提供了全面的解决方案,TapCardSDK
可以使用所有可能的技术进行安装。
Cocoapods
target 'MyApp' do
pod 'Card-SDK-iOS'
end
然后在终端中运行:
pod install
pod update
Swift 包管理器
在 Xcode 中,将 TapCardSDK
添加为 Xcode 项目的 包依赖项。将 https://github.com/Tap-Payments/Card-SDK-iOS.git 作为包 URL。勾选 Tap-Card-SD
复选框以将 TapCardSDK
库添加到您的应用中。
准备输入
文档
为了使我们的 SDK 尽可能动态,我们接受许多配置作为输入。让我们先声明它们并解释它们的结构和每个配置的用法。
/**
Creates a configuration model to be passed to the SDK
- Parameters:
- publicKey: The Tap public key
- scope: The scope of the card sdk. Default is generating a tap token
- purpose: The intended purpose of using the generated token afterwards.
- merchant: The Tap merchant details
- transaction: The transaction details
- order: The tap order id
- invoice: Link this token to an invoice
- customer: The Tap customer details
- acceptance: The acceptance details for the transaction
- fields: Defines the fields visibility
- addons: Defines some UI/UX addons enablement
- interface: Defines some UI related configurations
*/
配置 | 描述 | 必需 | 类型 | 示例 |
---|---|---|---|---|
publicKey | 这是您在注册 bundle id 后获得的 Tap Key 。 |
True | String | let publicKey:String = "pk_test_YhUjg9PNT8oDlKJ1aE2fMRz7" |
scope | 定义使用 TapCardSDK 的意图。 |
True | String | let scope:String = "Token" //这意味着您将获得一个用于之后使用的 Tap 令牌 或 let scope:String = "Authenticate" //这意味着您将获得一个用于立即在我们的扣费 API 中使用的经过身份验证的 Tap 令牌 |
purpose | 定义生成令牌后使用令牌的意图。 | True | String | let purpose:String = "PAYMENT_TRANSACTION" //使用令牌进行一次扣费。 或 let purpose:String = "RECURRING_TRANSACTION" //使用令牌进行多次定期扣费。 或 let purpose:String = "INSTALLMENT_TRANSACTION" //使用令牌进行分期付款计划中的一部分扣费。 或 let purpose:String = "ADD_CARD" //使用令牌为顾客保存一张卡。 或 let purpose:String = "CARDHOLDER_VERIFICATION" //使用令牌来验证卡的拥有权。 |
transaction | 在生成经过身份验证的令牌时,需要定义交易元数据和引用。 | False | Dictionry |
let transaction:[String:Any] = ["metadata":["example":"value"], "reference":"A reference to this transaciton in your system"] |
order | 这是您创建的 Tap 订单ID 以及需要的数量和货币,如果有的话。 |
False | Dictionary |
定义订单:let order:[String:String] = ["id":"", "amount":1, "currency":"SAR", "description": "认证描述"] |
发票 | 这是您想要链接此令牌的发票 发票编号 (如果有)。 |
False | Dictionary |
定义发票:let invoice:[String:String] = ["id":""] |
商户 | 在注册您的捆绑ID后,这将为您提供 商户编号 。 |
True | Dictionary |
定义商户:let merchant:[String:String] = ["id":""] |
客户 | 您想要附加到令牌化过程的客户详细信息。 | True | Dictionary |
定义客户:let customer:[String:Any] = ["id":"", "name":[["lang":"en","first":"TAP","middle":"","last":"PAYMENTS"]], "nameOnCard":"TAP PAYMENTS", "editable":true, "contact":["email":"[email protected]", "phone":["countryCode":"+965","number":"88888888"]]] |
接受详情 | 交易的接受详情。包括,您想要允许客户对企业进行令牌化的卡品牌和类型。 | False | Dictionary |
定义接受详情:let acceptance:[String:Any] = ["supportedBrands": ["AMERICAN_EXPRESS","VISA","MASTERCARD","OMANNET","MADA"], "supportedCards":["CREDIT","DEBIT"] |
字段 | 用于定义卡表单中可选字段的可见性。 | False | Dictionary |
定义字段:let fields:[String:Bool] = ["cardHolder":true] |
附加功能 | 用于定义在基本卡表单上启用一些额外功能。 | False | Dictionary |
let addons:[String:Bool] = ["displayPaymentBrands": true, "loader": true, "scanner": false] /**- displayPaymentBrands: 定义显示支持的卡品牌徽标 - loader: 定义当卡在处理状态时显示加载动画 - scanner: 定义是否启用卡扫描功能*/ |
界面 | 用于定义与外观相关的配置。 | False | Dictionary |
定义界面:let interface:[String:String] = ["locale": "en", "theme": "light", "edges": "curved", "direction": "dynamic"] // 主题的有效值:light/dark。locale: en/ar,edges: curved/flat,direction:ltr/dynaimc |
POST请求 | 这是您的服务器上的 webhook ,如果要让我们在服务器之间更新。 |
False | Dictionary |
定义POST请求:let post:[String[String] = ["url":""] |
初始化输入
以字典的形式进行初始化
您可以创建一个字典来将数据传递给我们的sdk。好处在于,您可以从中生成您的API数据。每当配置有更新时,您可以更新您的API。这将确保您不需要在App Store上更新您的应用程序。
var dictConfig: [String: Any] = [
"publicKey": "pk_test_YhUjg9PNT8oDlKJ1aE2fMRz7",
"scope": "Authenticate",
"purpose": "PAYMENT_TRANSACTION",
"transaction": [
"metadata": ["example": "value"],
"reference": "",
],
"order": ["id": "",
"amount": 1,
"currency": "SAR",
"description": "Authentication description"],
"invoice": ["id": ""],
"merchant": ["id": ""],
"customer": [
"id": "",
"name": [["lang": "en", "first": "TAP", "middle": "", "last": "PAYMENTS"]],
"nameOnCard": "TAP PAYMENTS",
"editble": true,
"contact": [
"email": "[email protected]",
"phone": ["countryCode": "+965", "number": "88888888"],
],
],
"acceptance": [
"supportedBrands": ["AMERICAN_EXPRESS", "VISA", "MASTERCARD", "OMANNET", "MADA"],
"supportedCards": ["CREDIT", "DEBIT"],
],
"fields": ["cardHolder": true],
"addons": ["displayPaymentBrands": true, "loader": true, "saveCard": false, "scanner": false],
"interface": [
"locale": "en",
"theme": "light",
"edges": "curved", "direction": "dynamic",
],
"post": ["url": ""],
]
初始化TapCardSDK表单
您可以通过不同的方式初始化TapCardView
- 故事板。
- 代码。
- SwiftUI
故事板
代码
/// A class level variable
var tapCardView:TapCardView = .init()
/// The configuration dictionary
var dictConfig:[String:Any] = ["publicKey":"pk_test_YhUjg9PNT8oDlKJ1aE2fMRz7",
"scope":"Authenticate",
"purpose":"PAYMENT_TRANSACTION",
"transaction":["metadata":["example":"value"],
"reference":""],
"order":["id":"",
"amount":1,
"currency":"SAR",
"description": "Authentication description"],
"invoice":["id":""],
"merchant":["id":""],
"customer":["id":"",
"name":[["lang":"en","first":"TAP","middle":"","last":"PAYMENTS"]],
"nameOnCard":"TAP PAYMENTS",
"editble":true,
"contact":["email":"[email protected]",
"phone":["countryCode":"+965","number":"88888888"]]],
"acceptance":["supportedBrands":["AMERICAN_EXPRESS","VISA","MASTERCARD","OMANNET","MADA"],
"supportedCards":["CREDIT","DEBIT"]],
"fields":["cardHolder":true],
"addons":["displayPaymentBrands": true, "loader": true, "saveCard": false, "scanner": false],
"interface":["locale": "en", "theme": UIView().traitCollection.userInterfaceStyle == .dark ? "dark": "light", "edges": "curved", "direction": "dynamic"],
"post":["url":""]]
/// Add the needed constraints to show and put the card view within your layout
func addCardView() {
view.addSubview(tapCardView)
tapCardView.translatesAutoresizingMaskIntoConstraints = false
let constraints = [
tapCardView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
tapCardView.topAnchor.constraint(equalTo: view.topAnchor, constant: 100),
tapCardView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20),
tapCardView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 20),
view.heightAnchor.constraint(equalToConstant: 95)
]
NSLayoutConstraint.activate(constraints)
tapCardView.setNeedsLayout()
tapCardView.updateConstraints()
view.updateConstraints()
}
/// Pass the required configuration data to the tap card view sdk
func configureTheSDK() {
tapCardView.initTapCardSDK(configDict: dictConfig, delegate: self, presentScannerIn: self)
}
SwiftUI
TapCardViewDelegate
一个协议,允许集成商从TapCardSDK
触发的事件中得到通知。
@objc public protocol TapCardViewDelegate {
/// Will be fired whenever the card is rendered and loaded
@objc optional func onReady()
/// Will be fired once the user focuses any of the card fields
@objc optional func onFocus()
/// Will be fired once we detect the brand and related issuer data for the entered card data
/** - Parameter data: will include the data in JSON format. example :
*{
"bin": "424242",
"bank": "",
"card_brand": "VISA",
"card_type": "CREDIT",
"card_category": "",
"card_scheme": "VISA",
"country": "GB",
"address_required": false,
"api_version": "V2",
"issuer_id": "bnk_TS02A5720231337s3YN0809429",
"brand": "VISA"
}* */
@objc optional func onBinIdentification(data: String)
/// Will be fired whenever the validity of the card data changes.
/// - Parameter invalid: Will be true if the card data is invalid and false otherwise.
@objc optional func onInvalidInput(invalid: Bool)
/**
Will be fired whenever the card sdk finishes successfully the task assigned to it. Whether `TapToken` or `AuthenticatedToken`
- Parameter data: will include the data in JSON format. For `TapToken`:
{
"id": "tok_MrL97231045SOom8cF8G939",
"created": 1694169907939,
"object": "token",
"live_mode": false,
"type": "CARD",
"source": "CARD-ENCRYPTED",
"used": false,
"card": {
"id": "card_d9Vj7231045akVT80B8n944",
"object": "card",
"address": {},
"funding": "CREDIT",
"fingerprint": "gRkNTnMrJPtVYkFDVU485Gc%2FQtEo%2BsV44sfBLiSPM1w%3D",
"brand": "VISA",
"scheme": "VISA",
"category": "",
"exp_month": 4,
"exp_year": 24,
"last_four": "4242",
"first_six": "424242",
"name": "AHMED",
"issuer": {
"bank": "",
"country": "GB",
"id": "bnk_TS07A0720231345Qx1e0809820"
}
},
"url": ""
}
*/
@objc optional func onSuccess(data: String)
/// Will be fired whenever there is an error related to the card connectivity or apis
/// - Parameter data: includes a JSON format for the error description and error
@objc optional func onError(data: String)
/// Will be fired whenever the card element changes its height for your convience
/// - Parameter height: The new needed height
@objc optional func onHeightChange(height: Double)
}
令牌化卡
一旦您从代理得到通知,TapCardView
现在已经有有效输入。您可以通过调用公共接口开始令牌化过程。
/// Wil start the process of generating a `TapToken` with the current card data
tapCardView.generateTapToken()