Shift4 iOS SDK
欢迎使用Shift4 iOS SDK。该框架允许您轻松地将Shift4支付功能添加到您的移动应用程序中。它允许您仅用几行代码即可与Shift4集成。它还公开了低级别的Shift4 API,您可以使用它来创建自定义支付表单。
特性
安全
所有敏感数据都直接发送到我们的服务器,而不是使用您的后端,因此您可以确保您的支付安全性非常高。
3D-Secure
向您的交易添加智能3D-Secure验证,带来一流的UX体验。提供流畅、不间断的支付体验,不会干扰您的转化过程。
Shift4 API
我们提供与Shift4 API相对应的方法。它允许您创建一个完全定制的UI,嵌入到您的应用程序中,以保持客户在您的应用程序中,从而提高转化率。
翻译
您可以使用18种语言处理支付。
示例应用程序
我们创建了一个简单的应用程序来演示框架的功能。
要求和限制
PCI 3DS SDK的高标准要求使得开发变得不可能。在生产版本的应用中,运行模拟器或进行调试是禁止的。我们提供了两种版本的框架,包括调试和发布版本,以便您可以在不出现问题的情况下创建和调试您的应用。
请注意,使用框架的发布版本进行XCode的发布构建和AdHoc构建也是禁止的。尝试执行此操作将导致错误。唯一允许测试发布版本的工具有Apple TestFlight。
App Store 审查
为确保使用我们SDK的应用成功通过App Store审查流程,我们将其集成到Shift4 Sentinel应用中。它还允许您方便地熟悉我们的框架功能。为此,请下栽应用程序(https://apps.apple.com/us/app/shift4-sentinel/id6444154679),然后在“配置文件”标签中开启测试模式。屏幕底部将出现一个开发人员部分,其中包括框架的演示。
安装
CocoaPods
由于与XCFramework相关的问题,您必须使用CocoaPods 1.10.1或更高版本。
3D Secure库的许可要求迫使我们通过电子邮件分发。联系[email protected]获取它。下载ipworks3ds_sdk_debug.xcframework和ipworks3ds_sdk_release.xcframework 3D-Secure库,并将它们复制到项目根目录中的Frameworks目录。然后向构建阶段添加一个新的脚本来选择适当的3DS框架版本。
rm -rf ${SRCROOT}/ipworks3ds_sdk.xcframework
if [ $CONFIGURATION == "Release" ]; then
cp -rf ${SRCROOT}/Frameworks/ipworks3ds_sdk_release.xcframework ${SRCROOT}/ipworks3ds_sdk.xcframework
fi
if [ $CONFIGURATION == "Debug" ]; then
cp -rf ${SRCROOT}/Frameworks/ipworks3ds_sdk_debug.xcframework ${SRCROOT}/ipworks3ds_sdk.xcframework
fi
这一步在示例应用中被称为复制Shift4 3DS框架
,您可以在其中进行检查。
然后构建一个应用程序。新文件 ipworks3ds_sdk.xcframework 将出现在您的项目根目录中。将其添加到您的项目中。选择 嵌入并签名
选项。
接下来,您需要使用 Cocoapods 安装框架。在 Podfile 中添加以下条目
pod 'Shift4'
然后运行 pod install --repo-update
。
不要忘记在您想要使用 Shift4 的任何文件的开头导入框架。
Swift
import Shift4
Objective-C
@import Shift4;
使用方法
如果您还没有创建账户,可以在此处创建: https://dev.shift4.com/signup。
配置
要配置框架,您需要提供公钥。您可以在以下位置找到它: https://dev.shift4.com/account-settings。请注意,存在两种类型的密钥:实时和测试。密钥类型确定应用程序模式。确保您在发布到 App Store 的构建中使用的是实时密钥。您还可以在后端提供此密钥。
框架还要求您指定应用的程序包标识符。这应该与应用程序构建时使用的程序包标识符匹配。如果它们不匹配,则在发布模式下尝试执行该操作会导致错误。出于安全原因,此值不应该在应用中硬编码。您应该在您的后端提供它。
Swift
Shift4SDK.shared.publicKey = "pk_test_..."
Shift4SDK.shared.bundleIdentifier = "..."
Objective-C
Shift4SDK.shared.publicKey = @"pk_test_...";
Shift4SDK.shared.bundleIdentifier = @"";
Checkout View Controller
Checkout View Controller是一种内置解决方案,旨在提供无缝的支付体验。这是一个简单且可用的支付组件,它会出现在您页面的上方。
要显示Checkout View Controller,您需要在您的后端创建Checkout请求。有关Checkout请求的更多信息,请参阅此处:[Checkout请求](https://dev.shift4.com/docs/api#checkout-request)。您也可以在此处创建测试Checkout请求:[测试请求生成器](https://dev.shift4.com/docs/checkout-request-generator)。
Swift
let checkoutRequest = ...
Shift4SDK.shared.showCheckoutViewController(
in: self,
checkoutRequest: checkoutRequest) { [weak self] result, error in
if let result = result {
print(result.subscriptionId)
print(result.chargeId)
} else if let error = error {
print(error.localizedMessage())
} else {
// cancelled
}
}
Objective-C
SPCheckoutRequest* checkoutRequest = ...;
[[Shift4 shared] showCheckoutViewControllerIn:self
checkoutRequest:checkoutRequest
completion:^(SPPaymentResult * result, SPError * error) {
if (result != nil) {
NSLog(@"%@", result.subscriptionId);
NSLog(@"%@", result.chargeId);
} else if (error != nil) {
NSLog(@"%@", [error localizedMessage]);
} else {
// Cancelled
}
}];
已保存卡
结算视图控制器有一个功能可以记住之前使用的卡。要删除它们,请使用以下代码
Swift
Shift4SDK.shared.cleanSavedCards()
Objective-C
[[Shift4 shared] cleanSavedCards];
可能的错误
类型 | 代码 | 消息 | 解释 |
---|---|---|---|
.sdk | .unsupportedValue | "不支持的值:(值)" | 框架不接受结算请求字段:`termsAndConditionsUrl`、`customerId`、`crossSaleOfferIds`。 |
.sdk | .incorrectCheckoutRequest | "不正确的结算请求" | 结算请求看起来已损坏。请确保您根据文档创建它。 |
.threeDSecure | .unknown | "未知3D Secure错误。检查您的SDK集成。" | |
.threeDSecure | .deviceJailbroken | "设备已越狱。" | |
.threeDSecure | .integrityTampered | "SDK 的完整性已被篡改。" | |
.threeDSecure | .simulator | "正在使用模拟器运行应用程序。" | |
.threeDSecure | .osNotSupported | "不支持的操作系统或操作系统版本。" |
SDK 允许用户以模态框的形式显示 3DS 认证屏幕。
let request = TokenRequest(
number: "4242424242424242",
expirationMonth: "10",
expirationYear: "2023",
cvc: "123"
)
Shift4SDK.shared.createToken(with: request) { token, error in
guard let self = self else { return }
guard let token = token else { print(error); return }
Shift4SDK.shared.authenticate(token: token, amount: 10000, currency: "EUR", viewControllerPresenting3DS: self) { [weak self] authenticatedToken, authenticationError in
print(authenticatedToken)
print(authenticationError)
}
}
类型 | 代码 | 消息 | 解释 |
---|---|---|---|
.cardError | .invalidNumber | "信用卡号不是有效的信用卡号码。" | |
.cardError | .invalidExpiryMonth | "信用卡的到期月份无效。" | |
.cardError | .invalidExpiryYear | "信用卡的到期年份无效。" | |
.cardError | .expiredCard | "信用卡已过期。" | |
.cardError | .invalidCVC | "您的信用卡安全码无效。" |
类型 | 代码 | 消息 | 解释 |
---|---|---|---|
.sdk | 执行另一个操作 | "另一个任务正在进行中。" | 您一次只能完成一个身份验证操作。您的UI应该防止其多次触发。 |
.threeDSecure | .unknown | "未知3D Secure错误。检查您的SDK集成。" | |
.threeDSecure | .deviceJailbroken | "设备已越狱。" | |
.threeDSecure | .integrityTampered | "SDK 的完整性已被篡改。" | |
.threeDSecure | .simulator | "正在使用模拟器运行应用程序。" | |
.threeDSecure | .osNotSupported | "不支持的操作系统或操作系统版本。" |
Flutter
该SDK使用原生技术创建,但由于Flutter允许您使用原生组件,因此在该平台上集成库是可能的,但需要额外的几个步骤。
首先,打开主项目目录中的/ios子目录下的Xcode项目文件。然后执行安装部分中描述的配置。别忘了请求3D-Secure库,因为没有这个库您无法编译项目,并且由于许可原因,我们不能将其发布到GitHub。您可以通过联系 [email protected] 来获取它。
在AppDelegate.swift中的原生iOS代码中创建一个函数
private func performCheckout(result: @escaping FlutterResult) {
let checkoutRequest = CheckoutRequest(content: "...")
Shift4SDK.shared.publicKey = "pk_test_..."
Shift4SDK.shared.bundleIdentifier = "com.example.app"
Shift4SDK.shared.showCheckoutViewController(in: (window?.rootViewController)!, checkoutRequest: checkoutRequest, merchantName: "Example merchant", description: "Example payment") { paymentResult, paymentError in
if let paymentResult {
result(paymentResult.dictionary())
} else if let paymentError {
result(paymentError.dictionary())
} else {
// Cancelled
}
}
}
在didFinishLaunching函数中添加以下行
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let checkoutChannel = FlutterMethodChannel(name: "com.example/checkout", binaryMessenger: controller.binaryMessenger)
checkoutChannel.setMethodCallHandler({ [weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
guard call.method == "checkout" else {
result(FlutterMethodNotImplemented)
return
}
self?.performCheckout(result: result)
})
请确保提供正确的publicKey、bundleIdentifier和checkoutRequest。分包标识符不应硬编码到应用程序中,而应从您的服务器提供。
在您的应用程序状态中添加以下行
static const platform = MethodChannel('com.example/checkout');
Future<void> _checkout() async {
try {
final Map result = await platform.invokeMethod('checkout');
print(result);
} on PlatformException catch (e) {
print(e);
}
}
并在某个地方执行创建的函数,例如创建一个按钮
TextButton(
onPressed: _checkout,
child: const Text('Hello Shift4!')),
好了。您现在可以启动应用程序了。
React Native
该SDK使用原生技术创建,但由于React Native允许您使用原生组件,因此在该平台上集成库是可能的,但需要额外的几个步骤。
首先,打开主项目目录中/ios子目录下的Xcode项目文件。然后执行安装部分中描述的配置。别忘了请求3D-Secure库,因为没有这个库您无法编译项目,并且由于许可原因,我们不能将其发布到GitHub。您可以通过联系 [email protected] 来获取它。
在Xcode中的原生iOS代码中创建Shift4Bridge类
// Shift4Bridge.h
#import <Foundation/Foundation.h>
#import <React/RCTBridgeModule.h>
NS_ASSUME_NONNULL_BEGIN
@interface Shift4Bridge : NSObject <RCTBridgeModule>
@end
NS_ASSUME_NONNULL_END
// Shift4Bridge.m
#import "Shift4Bridge.h"
@import Shift4;
@import React;
@implementation Shift4Bridge
- (dispatch_queue_t)methodQueue
{
return dispatch_get_main_queue();
}
RCT_EXPORT_MODULE(Shift4Bridge);
RCT_REMAP_METHOD(hook,
checkoutRequest:(nonnull NSString *)checkoutRequest
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
id cr = [[S4CheckoutRequest alloc] initWithContent:checkoutRequest];
[Shift4SDK shared].publicKey = @"pk_test_...";
[Shift4SDK shared].bundleIdentifier = @"com.example.app";
[[Shift4SDK shared] showCheckoutViewControllerIn:RCTPresentedViewController() checkoutRequest:cr merchantName:@"Example merchant" description:@"Example payment" merchantLogo:nil collectShippingAddress:NO collectBillingAddress:NO email:nil completion:^(S4PaymentResult * _Nullable result, S4Error * _Nullable error) {
if (result != nil) {
resolve([NSDictionary dictionaryWithDictionary:[result dictionary]]);
}
if (error != nil) {
reject(@"Shift4 Error", [error localizedMessage], [NSError errorWithDomain:@"Shift4Bridge" code:100 userInfo:[NSDictionary dictionaryWithDictionary:[error dictionary]]]);
}
}];
}
@end
请确保提供正确的publicKey、bundleIdentifier和checkoutRequest。分包标识符不应硬编码到应用程序中,而应从您的服务器提供。
在React Native代码中创建一个按钮
<View style={styles.buttonContainer}>
<Button title="Press Me" onPress={handleButtonPress} />
</View>
及其处理程序
const handleButtonPress = () => {
NativeModules.Shift4Bridge.hook(
"checkout request content",
)
.then(result => {
Alert.alert(
'Success',
JSON.stringify(result),
[
{ text: 'OK', onPress: () => console.log('OK') },
],
{ cancelable: false }
);
})
.catch(error => {
Alert.alert(
'Error',
JSON.stringify(error),
[
{ text: 'OK', onPress: () => console.log('OK') },
],
{ cancelable: false }
);
});
};
好了。您现在可以启动应用程序了。
自定义
可以使用从 Shift4SDK.shared.style
返回的对象自由修改字体、颜色和尺寸等界面元素。以下为代码示例。
let style = Shift4SDK.shared.style
style.primaryColor = .blue
style.successColor = .green
style.errorColor = .red
style.primaryTextColor = .black
style.placeholderColor = .gray
style.disabledColor = .gray
style.separatorColor = .gray
style.button.font = UIFont.boldSystemFont(ofSize: 10)
style.button.height = 60.0
style.button.cornerRadius = 5.0
style.font.regularlabel = UIFont.systemFont(ofSize: 10)
style.font.title = UIFont.systemFont(ofSize: 10)
style.font.section = UIFont.systemFont(ofSize: 10)
style.font.body = UIFont.systemFont(ofSize: 10)
style.font.label = UIFont.systemFont(ofSize: 10)
style.font.error = UIFont.systemFont(ofSize: 10)
style.font.tileLabel = UIFont.systemFont(ofSize: 20)
primaryColor
用于按钮和开关的主品牌颜色。
successColor
支付成功后按钮的颜色。
errorColor
用于错误信息的颜色。
primaryTextColor
用于所有标题、部分和其他标签的颜色。
占位符颜色
文本输入框的占位符颜色。
禁用颜色
禁用元素的色彩,例如文本输入框为空时按钮禁用。
分隔符颜色
章节和其他影响页面结构的元素之间的分隔符颜色。
按钮字体
按钮标题的字体样式。
按钮高度
按钮的高度。
button.cornerRadius
按钮的圆角。如果您希望按钮是矩形,请使用0。
测试
在测试模式下进行请求时,您必须使用特殊的卡号来模拟成功的收费或处理错误。您可以在以下位置找到卡号列表:[链接](https://dev.shift4.com/docs/testing)。您可以在以下位置检查您进行的每次收费的状态:[链接](https://dev.shift4.com/charges)。
请记住,不要在短时间内发出过多请求,否则您可能会达到速率限制。如果达到限制,您必须等待24小时。
翻译
SDK支持18种语言的本地化。您的应用程序必须本地化。
许可
框架按照MIT许可证发布。