Authorize.Net In-Person iOS SDK集成指南
Authorize.Net In-Person SDK为EMV支付处理提供半集成解决方案。有关半集成环境及其中的交易工作流程概览,请参阅我们的Authorize.Net In-Person SDK概述。此SDK基于Authorize.Net API进行交易处理。有关Authorize.Net API的更详细信息,请参阅我们的API参考。有关常见问题解答,请参阅EMV常见问题解答页面。
您的应用程序调用SDK以完成EMV交易。SDK处理复杂的EMV工作流程,并安全地将EMV交易提交给Authorize.Net进行处理。在任何时候都不会接触到任何EMV数据。
要确定您使用的处理程序,您可以向getMerchantDetailsRequest提交API调用。响应包含包含有关您帐户配置为使用的处理程序信息的processors
对象。
支持的加密读取器
要确定您使用的处理程序,您可以向getMerchantDetailsRequest提交API调用。响应包含一个processors
对象。
可以从Authorize.Net POS Portal获取支持的读取器设备。
包括框架
-
将SDK框架包含在商户的应用程序中。使用Xcode将AnetEMVSdk.framework 文件包含在嵌入式二进制文件下。商户应用程序必须使用
密码
字段登录并初始化一个有效的商户对象。 -
包含额外的框架和设置。
a) 将libxml2.2.tbd文件包含到应用程序中。
b) 导航到 构建设置 > 搜索路径 > 标题搜索路径。
c) 输入以下设置:
Iphoneos/usr/include/libxml2
。d) 仅在将SDK作为静态库包含时,才需要此设置。请将以下模块链接到您的项目中
• AudioToolbox.framework • CoreAudio.framework • MediaPlayer.framework • MediaToolbox.framework • External Accessory.framework • AVFoundation.framework • CoreBluetooth.framework
-
复制包资源。
a) 在应用程序中包含来自AnetEMVSdk.framework 文件的
AnetEMVStoryBoard.storyboard
、OTAUpdate.png
和eject.mp3
字段。如果它们被正确包含,您应该能够在目标 > 构建阶段 > 复制包资源中看到它们。 -
如果应用程序是用Swift语言开发的,它必须有一个桥接头文件,因为AnetEMVSdk.framework 文件是基于Objective C的。
初始化SDK
有两种环境:用于与Authorize.Net沙箱环境集成的测试STAR和用于处理实际交易的实经历活。
使用AUTHNET_ENVIRONMENT设置在ApplicationDelegate或初始UIViewController中初始化单例。您还必须#导入AuthNet.h。
[AuthNet authNetWithEnvironment:ENV_TEST];
概述
Authorize.Net SDK支持MPoS解决方案的以下功能
移动设备认证
设备登录
/**
* Perform mobileDeviceLoginRequest on the AIM API.
* @param r The request to send.
*/
- (void) mobileDeviceLoginRequest:(MobileDeviceLoginRequest *)r;
此请求用于登录移动设备。可以通过设置UIViewController
的方式,使用AuthNet
类的setDelegate
方法,使应用程序仍然能够接收成功、失败和取消交易流程的回调。应用程序必须在其后续所有调用到Authorize.Net网关的API请求中填充由登录请求生成的sessionToken
。
设备登出
/**
* Perform logoutRequest on the AIM API.
* @param r The request to send.
*/
- (void) LogoutRequest:(LogoutRequest *)r;
执行LogoutRequest
登出请求。通过设置UIViewController
并调用AuthNet
类的setDelegate
方法,应用程序仍然可以接收成功、失败和取消交易流程的回调。
EMV交易处理
传统EMV
EMV交易操作流程
-
在POS应用中,选择卡支付。
-
将读卡器连接到设备。
-
插入带有EMV芯片的卡片,完成交易前请不要移除卡片。或者,也可以刷非EMV卡片。
-
如果卡片上只有一个兼容的支付应用,支付应用将自动选择。如果提示,选择支付应用,例如Visa信用卡或MasterCard借记卡。
-
确认金额。
-
如果在任何时间用户取消交易,交易将被取消。
使用 SDK 创建和提交 EMV 交易
初始化 AnetEMVSdk.framework 文件。
-
使用 US 货币和终端 ID 初始化 AnetEMVManager。请参阅 AnetEMVManager.h 文件和示例应用程序以获取更多详细信息。参数包括
skipSignature
和showReceipt
。 -
initWithCurrencyCode: terminalID: skipSignature: showReceipt
-
实例化
AnetEMVTransactionRequest
并填充所需值,类似于常规交易中的AuthNetRequest
。如果您使用 Swift 构建您的应用程序,请不要使用 SDK 提供的静态方法来初始化对象。此外,AnetEMVSdk
需要应用程序提供presentingViewController
、一个获取 SDK 关于提交的交易响应的完成块,以及一个取消块以在 SDK 中执行取消操作。 -
应在
AnetEMVTransactionRequest
中提及EMVTransactionType
。请参阅 AnetEMVTransactionRequest.h 文件以获取所有可填充的枚举。 -
在创建所有所需对象后,调用 AnetEMVManager 的以下方法以提交交易。
[startEMVWithTransactionRequest:presentingViewController:completionBlock:andCancelActionBlock]
快速芯片
快速芯片交易操作流程
-
在 POS 应用程序中,选择“通过卡片支付”。
-
如果尚未连接,请将读卡器连接到设备。
-
插入一张带有 EMV 芯片的卡片,直到终端要求您取出卡片为止。或者,也可以滑动非 EMV 卡片。
-
如果卡片上只有一个兼容的支付应用,支付应用将自动选择。如果提示,选择支付应用,例如Visa信用卡或MasterCard借记卡。
-
确认金额。
-
如果在任何时间用户取消交易,交易将被取消。
使用 SDK 创建并提交快速芯片 EMV 交易
初始化 AnetEMVSdk.framework 文件。
- 使用 US 货币和终端 ID 初始化 AnetEMVManager。请参阅 AnetEMVManager.h 文件和示例应用程序以获取更多详细信息。参数包括
skipSignature
和showReceipt
。
initWithCurrencyCode: terminalID: skipSignature: showReceipt
- 设置终端模式,SDK 允许
AnetEMVModeSwipe
或AnetEMVModeInsertOrSwipe
。默认选择AnetEMVModeInsertOrSwipe
,它除了接受基于芯片的交易外,还可以接受滑动/MSR 交易,而AnetEMVModeSwipe
仅为 MSR/滑动交易。
- (void)setTerminalMode:(AnetEMVTerminalMode)iTerminalMode;
- 默认选择
AnetEMVModeInsertOrSwipe
。 - 请参阅 AnetEMVManager.h 文件和示例应用程序以获取更多详细信息。
-
实例化
AnetEMVTransactionRequest
并填充所需的值,类似于常规交易中的AuthNetRequest
。如果您使用 Swift 构建应用程序,请不要使用 SDK 提供的静态方法来初始化对象。AnetEMVSdk
需要应用程序提供presentingViewController
、用于从 SDK 获取提交的交易响应的完成块以及用于在 SDK 内部执行取消操作的取消块。 -
EMVTransactionType
应在AnetEMVTransactionRequest
中提及。有关所有可用枚举以填充,请参阅 AnetEMVTransactionRequest.h 文件。 -
创建所有必需的对象后,调用 AnetEMVManager 的以下方法之一并提交交易。
-
要连接到蓝牙,设置 EMV 读取器的连接模式。EMV 读取器可以通过音频或蓝牙连接连接到 iOS 设备。
- (void)setConnectionMode:(AnetEMVConnectionMode)iConnectionMode;
-
默认情况下选择音频连接。
-
设置
AnetEMVManager
的BTScanDeviceListBlock(deviceListBlock)
和BTDeviceConnected(deviceConnectedBlock)
。 -
调用
AnetEMVManager
的scanBTDevicesList
方法。这将搜索附近的设备并执行deviceListBlock
。 -
将列表显示给用户。
-
在用户选择后,调用 connectBTDeviceAtIndex 并传入所选索引。SDK 将尝试与所选列表中的设备连接。若连接成功或失败,SDK 将执行 deviceConnectedBlock。
-
请参阅 AnetEMVManager.h 文件和示例应用程序以获取更多详细信息。
快速芯片交易
如果将 iPaperReceiptCase
参数设置为 false,则此 API 将授权和捕获交易。如果将 iPaperReceiptCase
参数设置为 true,则 SDK 仅授权交易。您的应用程序必须用/不用小费金额结算/捕获交易。如果您的应用程序未能结算/捕获交易,授权的金额将在几天后释放。
`[- (void)startQuickChipWithTransactionRequest:(AnetEMVTransactionRequest * _Nonnull)iTransactionRequest forPaperReceiptCase:(BOOL)iPaperReceiptCase presentingViewController:(UIViewController * _Nonnull)iPresentingController completionBlock:(RequestCompletionBlock _Nonnull)iRequestCompletionBlock andCancelActionBlock:(CancelActionBlock _Nonnull)iCancelActionBlock]`
带小费金额的快速芯片交易
`[- (void)startQuickChipWithTransactionRequest:(AnetEMVTransactionRequest * _Nonnull)iTransactionRequest tipAmount:(NSString * _Nonnull)iTipAmount presentingViewController:(UIViewController * _Nonnull)iPresentingController completionBlock:(RequestCompletionBlock _Nonnull)iRequestCompletionBlock andCancelActionBlock:(CancelActionBlock _Nonnull)iCancelActionBlock]`
带小费选项的快速芯片交易
此 API 将在 SDK 的签名屏幕上显示小费百分比。您的应用程序可以发送三个小费百分比选项。小费选项必须是整数。SDK 将根据所选的小费选项计算并捕获小费金额。
`[- (void)startQuickChipWithTransactionRequest:(AnetEMVTransactionRequest * _Nonnull)iTransactionRequest tipOptions:(NSArray * _Nonnull)iTipOptions presentingViewController:(UIViewController * _Nonnull)iPresentingController completionBlock:(RequestCompletionBlock _Nonnull)iRequestCompletionBlock andCancelActionBlock:(CancelActionBlock _Nonnull)iCancelActionBlock]`
注意:只支持商品、服务和支付类型字段中的 TransactionType
。
成功
成功时,完成块应提供包含交易响应所需信息的 AnetEMVTransactionResponse
对象,并且 isTransactionSuccessful
将为 true。有关详细信息,请参阅 AnetEMVTransactionResponse.h。 emvResponse
包含 tlvdata
和响应中的所有标签。
错误
在出现交易错误的情况下,AnetEMVTransactionResponse
对象应包含错误详情。
在出现其他错误的情况下,AnetEMVError
对象应能够提供详情。
有关详细信息,请参阅 AnetEMVError.h。亦请参阅 AnetEMVManager.h 中的 ANETEmvErrorCode 枚举以获取有关错误的更多信息。
处理卡片数据
SDK 的快速芯片功能使您的应用程序能够在最终金额准备好之前处理卡片数据。处理卡片数据不进行授权或捕获交易。它检索卡片数据并将其存储在 SDK 内部的飞行模式下。当您的应用程序准备好最终金额时,您的应用程序必须发起一个快速芯片交易以捕获处理过的卡片数据。当您的应用程序调用处理卡片数据的方法时,以下快速芯片交易会对处理过的卡片数据进行收费。
[- (void)readQuickChipCardDataWithPredeterminedAmountOnViewController:(UIViewController * _Nonnull)iViewController transactionType:(EMVTransactionType)iEmvTransactionType
withCardInteractionProgressBlock:(CardIntercationProgressBlock _Nonnull)iCardInteractionProgressBlock andCardIntercationCompletionBlock:(CardIntercationCompletionBlock _Nonnull)iCardIntercationCompletionBlock]
如果您的应用程序未对处理过的卡片进行收费,您的应用程序必须调用丢弃卡片数据方法。在处理卡片数据之后的所有快速芯片调用都会对处理过的卡片进行收费,当 SDK 收费处理过的卡片数据后,将删除卡片数据。
[- (BOOL)discardQuickChipCardDataWithPredeterminedAmount]
配置 UI
您可以配置 In-Person SDK 的 UI 以匹配您的应用程序的 UI。在使用 SDK 之前,您的应用程序必须初始化这些值。如果没有设置值或者任何一个参数设置为 null,SDK 将默认使用其原始主题。
商户应用程序可以配置以下 UI 参数
-
背景颜色
-
文本字体颜色
-
按钮字体颜色
-
按钮背景颜色
-
横幅图片
-
横幅背景颜色
-
背景图片
代码示例
AnetEMVUISettings
字段公开了要设置的属性
背景颜色
AnetEMVUISettings.sharedUISettings ().backgroundColor = [UIColor blueColor];
文本字体颜色
AnetEMVUISettings.sharedUISettings ().textFontColor = [UIColor blackColor];
按钮字体颜色
AnetEMVUISettings.sharedUISettings ().buttonTextColor = [UIColor blueColor];
按钮背景颜色
AnetEMVUISettings.sharedUISettings ().buttonColor = [UIColor blueColor];
横幅图片
AnetEMVUISettings.sharedUISettings ().logoImage = [UIImage imageNamed:@"ANetLogo.png"];
横幅背景颜色
AnetEMVUISettings.sharedUISettings ().bannerBackgroundColor = [UIColor yellowColor];
背景图片
AnetEMVUISettings.sharedUISettings ().backgroundImage = [UIImage imageNamed:@"ANetBgImage.png"];
签名屏幕背景图片 AnetEMVUISettings.sharedUISettings ().signatureScreenBackgroundImage = [UIImage imageNamed:@"ANetSignatureScreenBgImage.png"];
签名垫背景图片 AnetEMVUISettings.sharedUISettings ().signaturePadBackgroundImage = [UIImage imageNamed:@"ANetSignaturePadBgImage.png"];
签名垫边框颜色 AnetEMVUISettings.sharedUISettings ().signaturePadBorderColor = [UIColor blackColor];
签名垫边框宽度 AnetEMVUISettings.sharedUISettings ().signaturePadBorderWidth = 5.0;
签名垫圆角大小 AnetEMVUISettings.sharedUISettings ().signaturePadCornerRadius = 5.0;
非EMV交易处理
SDK包含AuthNet类中支持的所有API方法的API
- 授权
- 购买
- 仅捕获
- 捕获先前授权
- 作废
- 信用
- 解除链接的信用
/**
* Perform AUTH transaction with request.
* @param r The request to send.
*/
- (void) authorizeWithRequest:(CreateTransactionRequest *)r;
执行授权请求。应用程序将通过设置带有AuthNet
类setDelegate
调用的UIViewController
来接收成功、失败和取消的交易流的代理回调。
/**
* Perform AUTH_CAPTURE transaction with request.
* @param r The request to send.
*/
- (void) purchaseWithRequest:(CreateTransactionRequest *)r;
执行购买请求。此请求同时执行授权和捕获。应用程序将通过设置带有AuthNet
类setDelegate
调用的UIViewController
来接收成功、失败和取消的交易流的代理回调。
/**
* Perform PRIOR_AUTH_CAPTURE transaction with request.
* @param r The request to send.
*/
- (void) captureWithRequest:(CreateTransactionRequest *)r;
执行捕获请求。此请求捕获通过Authorize.Net网关授权的交易。应用程序将通过设置带有AuthNet
类setDelegate
调用的UIViewController
来接收成功、失败和取消的交易流的代理回调。
/**
* Perform CAPTURE_ONLY transaction with request.
* NOTE: Request must include the authCode (x_auth_code).
* @param r The request to send.
*/
- (void) captureWithRequest:(CreateTransactionRequest *)r;
执行PRIOR_AUTH_CAPTURE请求。应用程序将通过设置带有AuthNet
类setDelegate
调用的UIViewController
来接收成功、失败和取消的交易流的代理回调。
/**
* Perform VOID transaction with request.
* @param r The request to send.
*/
- (void) voidWithRequest:(CreateTransactionRequest *)r;
执行作废请求。应用程序将通过设置带有AuthNet
类setDelegate
调用的UIViewController
来接收成功、失败和取消的交易流的代理回调。
/**
* Perform CREDIT transaction with request.
* @param r The request to send.
*/
- (void) creditWithRequest:(CreateTransactionRequest *)r;
执行信用请求。应用程序将通过设置带有AuthNet
类setDelegate
调用的UIViewController
来接收成功、失败和取消的交易流的代理回调。
/**
* Perform unlinked CREDIT transaction with request.
* NOTE: Unlinked Credit request must not have a transaction id (x_trans_id) value.
* @param r The request to send.
*/
- (void) unlinkedCreditWithRequest:(CreateTransactionRequest *)r;
不使用UIButton回调机制执行脱链信用请求。应用将通过设置AuthNet
类的setDelegate
调用中的UIViewController
接收成功、失败和取消交易流式的委托回调。
在交易中使用自己的UI创建客户资料
交易响应包含交易ID以及从客户处获得的客户资料详情。以下示例不使用包含的UI,因此您必须在应用中提供自己的表单来从用户处获取输入。
方法调用
//Create customer profile object.
CustomerProfileBaseType *customerProfile = [CustomerProfileBaseType customerProfileBaseType];
customerProfile.email = @"[email protected]";
customerProfile.merchantCustomerId = @"abc";
customerProfile.desc = @"xyz";
//Create payment profile object.
CustomerPaymentProfileType *customerPaymentProfile = [CustomerPaymentProfileType customerPaymentProfileType];
CustomerAddressType *address = [CustomerAddressType customerAddressType];
address.firstName = @"abc";
address.lastName = @"def";
address.city = @"New york";
address.state = @"CA";
address.country = @"USA";
address.zip = @"94585";
address.company = @"lmn";
address.phoneNumber = @"02014585485";
address.address = @"Mt street";
address.faxNumber = @"857458547965";
customerPaymentProfile.billTo = address;
//Call the provided API for creating customer profile
AnetCustomerProfileManager *manager = [AnetCustomerProfileManager sharedInstance];
[manager createCustomerProfileAndPaymentProfile:self.transactionID withMerchantAuthentication:self.merchantAuthentication withCustomerProfile:customerProfile withCustomerPaymentProfile: customerPaymentProfile successBlock:^ (id _Nullable response) {
}
failureBlock:^ (AnetCustomerProfileError *error){
}];
使用SDK中包含的UI从交易中创建客户资料
要使用SDK中包含的UI从交易中创建客户资料,在创建交易时,创建资料和支付资料对象并将它们传递给EMV交易对象。您必须发送一个布尔值,该值决定是否在交易前后获取创建资料的同意。
交易完成后,SDK内部将创建交易IS和客户资料。资料创建时,同时将支付交易结果和资料结果对象发送到调用应用。
创建对象
//Create customer profile object.
CustomerProfileBaseType *customerProfile = [CustomerProfileBaseType customerProfileBaseType];
customerProfile.email = @"[email protected]";
customerProfile.merchantCustomerId = @"abc";
customerProfile.desc = @"xyz";
//Create payment profile object.
CustomerPaymentProfileType *customerPaymentProfile = [CustomerPaymentProfileType customerPaymentProfileType];
CustomerAddressType *address = [CustomerAddressType customerAddressType];
address.firstName = @"abc";
address.lastName = @"def";
address.city = @"New york";
address.state = @"CA";
address.country = @"USA";
address.zip = @"94585";
address.company = @"lmn";
address.phoneNumber = @"02014585485";
address.address = @"Mt street";
address.faxNumber = @"857458547965";
customerPaymentProfile.billTo = address;
方法详情
/**
* Create a Customer Profile and Start a Quick Chip transaction with EMV request, presenting view controller and completion block.
* @param iTransactionRequest A request object of AnetEMVTransactionRequest
* @param iPaperReceiptCase if this is true then the Merchant needs to get the paper receipt signed by the customer and settle the transaction later on.
* @param iConsentBefore TRUE if consent should be taken before transaction otherwise FALSE.
* @param iPresentingController A presenting controller object. EMV controller will be presented on top of it
* @param iRequestCompletionBlock A completion block. Block will be executed on success or failure of Customer Profile creation
* @param iTransactionCompletionBlock A completion block. Block will be executed on success or failure of EMV transaction
* @param iCancelActionBlock A Cancel block. Block will be executed when cancel action is taken
*/
- (void)createCustomerProfile:(AnetEMVTransactionRequest * _Nonnull)iTransactionRequest
forPaperReceiptCase:(BOOL)iPaperReceiptCase
isConsentBefore:(BOOL)iConsentBefore
presentingViewController:(UIViewController * _Nonnull)iPresentingController
completionBlock:(ProfileCompletionBlock _Nonnull)iRequestCompletionBlock
transactionCompletionBlock:(TransactionCompletionBlock _Nonnull)iTransactionCompletionBlock
andCancelActionBlock:(CancelActionBlock _Nonnull)iCancelActionBlock;
使用您自己的UI从交易中创建额外的支付配置文件
要使用交易信息向客户配置文件添加附加支付配置文件,在交易完成后,将付款详细信息对象、客户配置文件ID和交易ID发送到SDK。您可以创建自定义UI以收集客户数据。
方法详情
/**
* Create an additional payment profile.
* @param iProfileID CustomerAddressType iTransactionID: Profile ID, Transaction ID and AnetCustomerProfileManager will provide success and failure block.
* @param iRequestCompletionBlock A completion block. Block will be executed on success with response object.
* @param iRequestFailureBlock A failure block. Block will be executed when request is failure with AnetCustomerProfileError object.
*/
- (void)createAdditionalPaymentProfileWithProfileID:(NSString *_Nonnull)iProfileID withCustomerPaymentProfile:(CustomerAddressType *_Nonnull)iAddress withTransactionID:(NSString *_Nonnull)iTransactionID withMerchantAuthentication:(MerchantAuthenticationType *_Nonnull)iMerchant successBlock:(CustomerProfileSuccessBlock _Nonnull)iRequestCompletionBlock failureBlock:(FailureBlock _Nonnull)iRequestFailureBlock;
使用SDK内自带的UI从交易中创建额外的支付配置文件
在交易过程中,用户将客户配置文件ID与交易详情一起发送。当付款交易完成后,SDK本身内会为有用户同意的现有客户创建支付配置文件。
方法详情
/**
* Create an Additional Payment Profile and Start a Quick Chip transaction with EMV request, presenting view controller and completion block.
* @param iTransactionRequest A request object of AnetEMVTransactionRequest
* @param iPaperReceiptCase if this is true then the Merchant needs to get the paper receipt signed by the customer and settle the transaction later on.
* @param iConsentBefore TRUE if consent should be taken before transaction otherwise FALSE.
* @param iPresentingController A presenting controller object. EMV controller will be presented on top of it
* @param iRequestCompletionBlock A completion block. Block will be executed on success or failure of Additional Payment Profile
* @param iTransactionCompletionBlock A completion block. Block will be executed on success or failure of EMV transaction
* @param iCancelActionBlock A Cancel block. Block will be executed when cancel action is taken
*/
- (void)createAdditionalPaymentProfile:(AnetEMVTransactionRequest * _Nonnull)iTransactionRequest
forPaperReceiptCase:(BOOL)iPaperReceiptCase
isConsentBefore:(BOOL)iConsentBefore
withCustomerProfileID:(NSString *_Nonnull)iProfileID
presentingViewController:(UIViewController * _Nonnull)iPresentingController
completionBlock:(ProfileCompletionBlock _Nonnull)iRequestCompletionBlock
transactionCompletionBlock:(TransactionCompletionBlock _Nonnull)iTransactionCompletionBlock
andCancelActionBlock:(CancelActionBlock _Nonnull)iCancelActionBlock;
客户电子邮件收据
/**
* Perform sendCustomerTransactionReceiptRequest on the AIM API.
* @param r The request to send.
*/
- (void) sendCustomerTransactionReceiptRequest:(SendCustomerTransactionReceiptRequest *) r;
执行一个sendCustomerTransactionReceiptRequest
请求。应用程序将通过设置AuthNet
类的setDelegate
调用中的UIViewController
来接收成功、失败和取消交易流程的委托回调。
交易报告
/**
* Perform getSettledBatchListRequest on the Reporting API.
* @param r The reporting request to send.
*/
- (void) getBatchStatisticsRequest:(GetBatchStatisticsRequest *) r;
执行 getBatchStatisticsRequest
请求。应用可以通过调用 AuthNet 类的 setDelegate
方法设置 UIViewController,来接收到成功、失败和取消的交易流程的代理回调。
/**
* Perform getSettledBatchListRequest on the Reporting API.
* @param r The reporting request to send.
*/
- (void) getSettledBatchListRequest:(GetSettledBatchListRequest *) r;
执行 getSettledBatchListRequest
请求。应用可以通过设置 UIViewController
的 setDelegate
调用,接收到成功、失败和取消的交易流程的代理回调。
/**
* Perform getTransactionDetailsRequest on the Reporting API.
* @param r The reporting request to send.
*/
- (void) getTransactionDetailsRequest:(GetTransactionDetailsRequest *) r;
执行 getTransactionDetailsRequest
请求。应用可以通过设置 UIViewController
的 setDelegate
调用,接收到成功、失败和取消的交易流程的代理回调。
/**
* Perform getTransactionDetailsRequest on the Reporting API.
* @param r The reporting request to send.
*/
- (void) getTransactionListRequest:(GetTransactionListRequest *) r;
执行 getTransactionListRequest
请求。应用可以通过设置 UIViewController
的 setDelegate
调用,接收到成功、失败和取消的交易流程的代理回调。
/**
* Perform getUnsettledTransactionListRequest on the Reporting API.
* @param r The reporting request to send.
*/
- (void) getUnsettledTransactionListRequest:(GetUnsettledTransactionListRequest *) r;
执行 getUnsettledTransactionListRequest
请求。应用可以通过设置 UIViewController
的 setDelegate
调用,接收到成功、失败和取消的交易流程的代理回调。
固件/配置更新
SDK 允许您通过空中(over the air)更新阅读器的固件或配置。阅读器设备由固件和配置文件驱动。您的应用可以检查阅读器设备上的当前固件和配置版本。
要从您的应用程序启动更新,请调用该方法,它将显示 UI,允许您确定设备是否需要更新。如果需要更新,用户将有选择进行配置/固件更新的选项。一旦选择选项,用户必须采取行动开始更新。SDK 显示更新进度。
[- (void)startOTAUpdateFromPresentingViewController:(UIViewController * _Nonnull) iPresentingController]
代码片段
- 在
ApplicationDelegate
或第一个UIViewController
中使用 AUTHNET_ENVIRONMENT 设置(指示是否访问测试环境或生产环境)初始化单例对象。请确保调用#import
AuthNet.h。
[AuthNet authNetWithEnvironment:ENV_TEST];
-
登录到 Authorize.Net 支付网关。
MobileDeviceLoginRequest *mobileDeviceLoginRequest = [MobileDeviceLoginRequest mobileDeviceLoginRequest];
mobileDeviceLoginRequest.anetApiRequest.merchantAuthentication.name = <USERNAME>;
mobileDeviceLoginRequest.anetApiRequest.merchantAuthentication.password = <PASSWORD>;
mobileDeviceLoginRequest.anetApiRequest.merchantAuthentication.mobileDeviceId = <PROVIDE A UNIQUE DEVICE IDENTIFIER>
AuthNet *an = [AuthNet getInstance];
[an setDelegate:self];
[an mobileDeviceLoginRequest: mobileDeviceLoginRequest];
Callback for the successful login
- (void) mobileDeviceLoginSucceeded:(MobileDeviceLoginResponse *)response {
sessionToken = [response.sessionToken retain];
};
-
使用加密Swiper数据的非EMV交易(IDTech Shuttle双轨安全磁条读卡器)
SwiperDataType *st = [SwiperDataType swiperDataType];
st.encryptedValue = self.encryptedCardDetails; // Encypted data be obtained with the IDTech Shuttle
st.deviceDescription = @îFID=IDTECH.UniMag.Android.Sdkv1î;
st.encryptionType = @îTDESî;
PaymentType *paymentType = [PaymentType paymentType];
payment.swiperData = st;
payment.creditCard.cardNumber = nil;
payment.creditCard.cardCode = nil;
payment.creditCard.expirationDate = nil;
ExtendedAmountType *extendedAmountTypeTax = [ExtendedAmountType extendedAmountType];
extendedAmountTypeTax.amount = @"0";
extendedAmountTypeTax.name = @"Tax";
ExtendedAmountType *extendedAmountTypeShipping = [ExtendedAmountType extendedAmountType];
extendedAmountTypeShipping.amount = @"0";
extendedAmountTypeShipping.name = @"Shipping";
LineItemType *lineItem = [LineItemType lineItem];
lineItem.itemName = @"AuthCaptureProduct";
lineItem.itemDescription = @"AuthCaptureProductDescription";
lineItem.itemQuantity = @"1";
lineItem.itemPrice = [NSString stringWithFormat:@"%d", [self randomDigit]];
lineItem.itemID = @"1";
TransactionRequestType *requestType = [TransactionRequestType transactionRequest];
requestType.lineItems = [NSMutableArray arrayWithObject:lineItem];
requestType.amount = lineItem.itemPrice;
requestType.payment = paymentType;
requestType.tax = extendedAmountTypeTax;
requestType.shipping = extendedAmountTypeShipping;
CreateTransactionRequest *request = [CreateTransactionRequest createTransactionRequest];
request.transactionRequest = requestType;
request.transactionType = AUTH_CAPTURE;
request.anetApiRequest.merchantAuthentication.mobileDeviceId = deviceId;
request.anetApiRequest.merchantAuthentication.sessionToken = self.loginResponse.sessionToken;
AuthNet *an = [AuthNet getInstance];
[an setDelegate:self];
[an purchaseWithRequest:request]; // transaction type can be changed depending upon the need of merchant application
// Merchant application would receive the encryptedValue in the below inteface of IDTech reader
- (BOOL)_interpretUnimagEncryptedSwipeData:(NSNotification*)notification {
self.encryptedCardDetails = @"";
NSData *data = [notification object];
NSString *val = [data description];
self.encryptedCardDetails = [val stringByReplacingOccurrencesOfString:@" " withString:@""];
self.encryptedCardDetails = [[self.encryptedCardDetails stringByReplacingOccurrencesOfString:@"<" withString:@""]stringByReplacingOccurrencesOfString:@">" withString:@""];
-
创建非-EMV交易。
• 购买交易(授权捕获)
CreditCardType *creditCardType = [CreditCardType creditCardType];
creditCardType.cardNumber = @"4111111111111111";
creditCardType.cardCode = @"100";
creditCardType.expirationDate = @"1222";
PaymentType *paymentType = [PaymentType paymentType];
paymentType.creditCard = creditCardType;
ExtendedAmountType *extendedAmountTypeTax = [ExtendedAmountType extendedAmountType];
extendedAmountTypeTax.amount = @"0";
extendedAmountTypeTax.name = @"Tax";
ExtendedAmountType *extendedAmountTypeShipping = [ExtendedAmountType extendedAmountType];
extendedAmountTypeShipping.amount = @"0";
extendedAmountTypeShipping.name = @"Shipping";
LineItemType *lineItem = [LineItemType lineItem];
lineItem.itemName = @"AuthCaptureProduct";
lineItem.itemDescription = @"AuthCaptureProductDescription";
lineItem.itemQuantity = @"1";
lineItem.itemPrice = [NSString stringWithFormat:@"%d", [self randomDigit]];
lineItem.itemID = @"1";
TransactionRequestType *requestType = [TransactionRequestType transactionRequest];
requestType.lineItems = [NSMutableArray arrayWithObject:lineItem];
requestType.amount = lineItem.itemPrice;
requestType.payment = paymentType;
requestType.tax = extendedAmountTypeTax;
requestType.shipping = extendedAmountTypeShipping;
CreateTransactionRequest *request = [CreateTransactionRequest createTransactionRequest];
request.transactionRequest = requestType;
request.transactionType = AUTH_CAPTURE;
request.anetApiRequest.merchantAuthentication.mobileDeviceId = deviceId;
request.anetApiRequest.merchantAuthentication.sessionToken = self.loginResponse.sessionToken;
AuthNet *an = [AuthNet getInstance];
[an setDelegate:self];
[an purchaseWithRequest:request];
• 仅授权交易(授权仅)
CreditCardType *creditCardType = [CreditCardType creditCardType];
creditCardType.cardNumber = @"4111111111111111";
creditCardType.cardCode = @"100";
creditCardType.expirationDate = @"1222";
PaymentType *paymentType = [PaymentType paymentType];
paymentType.creditCard = creditCardType;
ExtendedAmountType *extendedAmountTypeTax = [ExtendedAmountType extendedAmountType];
extendedAmountTypeTax.amount = @"0";
extendedAmountTypeTax.name = @"Tax";
ExtendedAmountType *extendedAmountTypeShipping = [ExtendedAmountType extendedAmountType];
extendedAmountTypeShipping.amount = @"0";
extendedAmountTypeShipping.name = @"Shipping";
LineItemType *lineItem = [LineItemType lineItem];
lineItem.itemName = @"AuthOnlyProduct";
lineItem.itemDescription = @"AuthOnlyProductDescription";
lineItem.itemQuantity = @"1";
lineItem.itemPrice = [NSString stringWithFormat:@"%d", [self randomDigit]];
lineItem.itemID = @"1";
TransactionRequestType *requestType = [TransactionRequestType transactionRequest];
requestType.lineItems = [NSMutableArray arrayWithObject:lineItem];
requestType.amount = lineItem.itemPrice;
requestType.payment = paymentType;
requestType.tax = extendedAmountTypeTax;
requestType.shipping = extendedAmountTypeShipping;
CreateTransactionRequest *request = [CreateTransactionRequest createTransactionRequest];
request.transactionRequest = requestType;
request.transactionType = AUTH_ONLY;
request.anetApiRequest.merchantAuthentication.mobileDeviceId = deviceId;
request.anetApiRequest.merchantAuthentication.sessionToken = self.loginResponse.sessionToken;
AuthNet *an = [AuthNet getInstance];
[an setDelegate:self];
[an authorizeWithRequest:request];
• 仅捕获(CAPTURE_ONLY)
CreditCardType *creditCardType = [CreditCardType creditCardType];
creditCardType.cardNumber = @"4111111111111111";
creditCardType.cardCode = @"100";
creditCardType.expirationDate = @"1222";
PaymentType *paymentType = [PaymentType paymentType];
paymentType.creditCard = creditCardType;
ExtendedAmountType *extendedAmountTypeTax = [ExtendedAmountType extendedAmountType];
extendedAmountTypeTax.amount = @"0";
extendedAmountTypeTax.name = @"Tax";
ExtendedAmountType *extendedAmountTypeShipping = [ExtendedAmountType extendedAmountType];
extendedAmountTypeShipping.amount = @"0";
extendedAmountTypeShipping.name = @"Shipping";
LineItemType *lineItem = [LineItemType lineItem];
lineItem.itemName = @"CaptureOnlyProduct";
lineItem.itemDescription = @"CaptureOnlyProductDescription";
lineItem.itemQuantity = @"1";
lineItem.itemPrice = [NSString stringWithFormat:@"%d", [self randomDigit]];
lineItem.itemID = @"1";
TransactionRequestType *requestType = [TransactionRequestType transactionRequest];
requestType.lineItems = [NSMutableArray arrayWithObject:lineItem];
requestType.amount = lineItem.itemPrice;
requestType.payment = paymentType;
requestType.tax = extendedAmountTypeTax;
requestType.shipping = extendedAmountTypeShipping;
requestType.authCode = @"ABC123";
CreateTransactionRequest *request = [CreateTransactionRequest createTransactionRequest];
request.transactionRequest = requestType;
request.transactionType = CAPTURE_ONLY;
request.anetApiRequest.merchantAuthentication.mobileDeviceId = deviceId;
request.anetApiRequest.merchantAuthentication.sessionToken = self.loginResponse.sessionToken;
AuthNet *an = [AuthNet getInstance];
[an setDelegate:self];
[an captureOnlyWithRequest:request];
• 已授权的捕获交易
CreditCardType *creditCardType = [CreditCardType creditCardType];
creditCardType.cardNumber = @"4111111111111111";
creditCardType.cardCode = @"100";
creditCardType.expirationDate = @"1222";
PaymentType *paymentType = [PaymentType paymentType];
paymentType.creditCard = creditCardType;
ExtendedAmountType *extendedAmountTypeTax = [ExtendedAmountType extendedAmountType];
extendedAmountTypeTax.amount = @"0";
extendedAmountTypeTax.name = @"Tax";
ExtendedAmountType *extendedAmountTypeShipping = [ExtendedAmountType extendedAmountType];
extendedAmountTypeShipping.amount = @"0";
extendedAmountTypeShipping.name = @"Shipping";
LineItemType *lineItem = [LineItemType lineItem];
lineItem.itemName = @"PriorAuthCaptureProduct";
lineItem.itemDescription = @"PriorAuthCaptureProductDescription";
lineItem.itemQuantity = @"1";
lineItem.itemPrice = [NSString stringWithFormat:@"%d", [self randomDigit]];
lineItem.itemID = @"1";
TransactionRequestType *requestType = [TransactionRequestType transactionRequest];
requestType.lineItems = [NSMutableArray arrayWithObject:lineItem];
requestType.amount = lineItem.itemPrice;
requestType.payment = paymentType;
requestType.tax = extendedAmountTypeTax;
requestType.shipping = extendedAmountTypeShipping;
CreateTransactionRequest *request = [CreateTransactionRequest createTransactionRequest];
request.transactionRequest = requestType;
request.transactionType = AUTH_ONLY;
request.anetApiRequest.merchantAuthentication.mobileDeviceId = deviceId;
request.anetApiRequest.merchantAuthentication.sessionToken = self.loginResponse.sessionToken;
AuthNet *an = [AuthNet getInstance];
[an setDelegate:self];
[an authorizeWithRequest:request];
requestType = [TransactionRequestType transactionRequest];
requestType.refTransId = self.transactionResponse.transactionResponse.transId;
requestType.payment = nil;
requestType.amount = lineItem.itemPrice;
request = [CreateTransactionRequest createTransactionRequest];
request.transactionRequest = requestType;
request.transactionType = PRIOR_AUTH_CAPTURE;
request.anetApiRequest.merchantAuthentication.mobileDeviceId = deviceId;
request.anetApiRequest.merchantAuthentication.sessionToken = self.loginResponse.sessionToken;
an = [AuthNet getInstance];
[an setDelegate:self];
[an captureWithRequest:request];
Callback for the non-emv transaction request
- (void) paymentSucceeded:(CreateTransactionResponse *) response {
// Handle payment success
}
-
撤销交易。
CreateTransactionRequest *request = [CreateTransactionRequest createTransactionRequest];
AuthNet *an = [AuthNet getInstance];
[an setDelegate:self];
request.transactionRequest.refTransId = self.transactionDetails.transId;
request.transactionRequest.amount = self.transactionDetails.settleAmount;
request.anetApiRequest.merchantAuthentication.sessionToken = sessionToken;
request.anetApiRequest.merchantAuthentication.mobileDeviceId = <PROVIDE A UNIQUE DEVICE IDENTIFIER>;
// Omit payment data for VOIDs
request.transactionRequest.payment = nil;
[an voidWithRequest:request];
Callback for the Void request
- (void) paymentSucceeded:(CreateTransactionResponse *) response {
// Handle payment success
}
-
退款交易。
CreateTransactionRequest *request = [CreateTransactionRequest createTransactionRequest];
AuthNet *an = [AuthNet getInstance];
[an setDelegate:self];
request.anetApiRequest.merchantAuthentication.sessionToken = sessionToken;
request.anetApiRequest.merchantAuthentication.mobileDeviceId = <PROVIDE A UNIQUE DEVICE IDENTIFIER>;
request.transactionRequest.refTransId = self.transactionDetails.transId;
request.transactionRequest.amount = self.transactionDetails.settleAmount;
request.transactionRequest.payment = [PaymentType paymentType];
request.transactionRequest.payment.creditCard.cardNumber = transactionDetails.payment.creditCard.cardNumber;
request.transactionRequest.payment.creditCard.expirationDate = transactionDetails.payment.creditCard.expirationDate;
[an creditWithRequest:request];
Callback for the Refund request
- (void) paymentSucceeded:(CreateTransactionResponse *) response {
// Handle payment success
}
-
请求结算批次列表
GetSettledBatchListRequest *r = [GetSettledBatchListRequest getSettlementBatchListRequest];
r.anetApiRequest.merchantAuthentication.sessionToken = sessionToken;
r.anetApiRequest.merchantAuthentication.mobileDeviceId = <PROVIDE A UNIQUE DEVICE IDENTIFIER>;
[[AuthNet getInstance] setDelegate:self];
[[AuthNet getInstance] getSettledBatchListRequest:r];
Callback
- (void) getSettledBatchListSucceeded:(GetSettledBatchListResponse *)response {
}
-
请求交易详情。
GetTransactionDetailsRequest *r = [GetTransactionDetailsRequest getTransactionDetailsRequest];
r.anetApiRequest.merchantAuthentication.sessionToken = sessionToken;
r.anetApiRequest.merchantAuthentication.mobileDeviceId = <PROVIDE A UNIQUE DEVICE IDENTIFIER>;
r.transId = transID;
[[AuthNet getInstance] setDelegate:self];
[[AuthNet getInstance] getTransactionDetailsRequest:r];
Callback
- (void) getTransactionDetailsSucceeded:(GetTransactionDetailsResponse *)response {
}
-
请求交易列表。
GetTransactionListRequest *r = [GetTransactionListRequest getTransactionListRequest];
r.anetApiRequest.merchantAuthentication.sessionToken = sessionToken;
r.anetApiRequest.merchantAuthentication.mobileDeviceId = <PROVIDE A UNIQUE DEVICE IDENTIFIER>;
// Batch Lists are from oldest to newest so use last object.
BatchDetailsType *b = [self.batchList lastObject];
r.batchId = [NSString stringWithString:b.batchId];
[self.batchList removeLastObject];
[[AuthNet getInstance] setDelegate:self];
[[AuthNet getInstance] getTransactionListRequest:r];
// Callback
- (void) getTransactionListSucceeded:(GetTransactionListResponse *)response {
}
-
请求未结算交易列表。
GetUnsettledTransactionListRequest *r = [GetUnsettledTransactionListRequest getUnsettledTransactionListRequest];
r.anetApiRequest.merchantAuthentication.sessionToken = sessionToken;
r.anetApiRequest.merchantAuthentication.mobileDeviceId = <PROVIDE A UNIQUE DEVICE IDENTIFIER>;
[[AuthNet getInstance] setDelegate:self];
[[AuthNet getInstance] getUnsettledTransactionListRequest:r];
// Callback
- (void) getUnsettledTransactionListSucceeded:(GetUnsettledTransactionListResponse *)response {
}
-
发送客户收据。
SendCustomerTransactionReceiptRequest *r = [SendCustomerTransactionReceiptRequest sendCustomerTransactionReceiptRequest];
r.anetApiRequest.merchantAuthentication.sessionToken = sessionToken;
r.anetApiRequest.merchantAuthentication.mobileDeviceId = <PROVIDE A UNIQUE DEVICE IDENTIFIER>;
r.customerEmail = self.currentEmail;
r.transId = self.transactionId;
SettingType *s = [SettingType settingType];
s.name = @"footerEmailReceipt";
// Append Transaction Type: Purchase
s.value = [NSString stringWithFormat:@"%@    Purchase<br/>", kTransactionType];
// Append Payment Method:
s.value = [s.value stringByAppendingFormat:@"%@    %@ %@<br/><br/>", kPaymentMethod, self.createTransactionResponse.transactionResponse.accountType, self.createTransactionResponse.transactionResponse.accountNumber];
// Append Boiler plate
s.value = [s.value stringByAppendingFormat:@"%@",kBoilerPlateCopy];
[r.emailSettings addObject:s];
s = [SettingType settingType];
s.name = @"headerEmailReceipt";
s.value = [NSString stringWithFormat:@"%@<br/>%@<br/>%@, %@ %@<br/>%@<br/>%@",
merchantName ? merchantName : @"",
merchantAddress ? merchantAddress : @"",
merchantCity ? merchantCity : @"",
merchantState ? merchantState : @"",
merchantZip ? merchantZip : @"",
merchantPhone ? merchantPhone : @"",
merchantEmailAddress ? merchantEmailAddress : @""];
[r.emailSettings addObject:s];
// Set delegate and send request
[[AuthNet getInstance] setDelegate:self];
[[AuthNet getInstance] sendCustomerTransactionReceiptRequest:r];
// Callback
- (void) sendCustomerTransactionReceiptSucceeded:(SendCustomerTransactionReceiptResponse *)response {
}
-
退出请求。
LogoutRequest *r = [LogoutRequest logoutRequest];
r.anetApiRequest.merchantAuthentication.sessionToken = sessionToken;
r.anetApiRequest.merchantAuthentication.mobileDeviceId = <PROVIDE A UNIQUE DEVICE IDENTIFIER>;
[[AuthNet getInstance] setDelegate:self];
[[AuthNet getInstance] LogoutRequest:r];
// Callback
- (void) logoutSucceeded:(LogoutResponse *)response {
}
错误代码
您可以在我们的响应代码原因工具中查看这些错误信息,通过输入特定的响应原因代码,那里将提供更多信息和建议。
字段顺序 | 响应码 | 响应原因码 | 文本 |
---|---|---|---|
3 | 2 | 355 | 解析EMV数据时发生错误。 |
3 | 2 | 356 | 此处理器和卡类型不支持基于EMV的交易。 |
3 | 2 | 357 | 需要不透明描述符。 |
3 | 2 | 358 | 此交易类型不支持EMV数据。 |
3 | 2 | 359 | 此市场类型不支持EMV数据。 |
3 | 2 | 360 | 解密EMV数据时发生错误。 |
3 | 2 | 361 | EMV版本无效。 |
3 | 2 | 362 | 需要x_emv_version。 |