此项目使 iOS API 能够与 payleven Classic (芯片 & PIN) 和 Plus (NFC) 卡读卡器通信,以便接收借记卡和信用卡付款。在 payleven 的某些国家的网站上了解更多关于卡读卡器的信息。[https://payleven.com/](https://payleven.com/) 从版本 1.1.0 开始,payleven Point Pay SDK 提供了一个用于处理全额和部分退款的 API。此外,SDK 还会发出包含最基本收据详情的销售和退款支付的收据图片。如果您有任何问题或需要进一步的帮助,请联系 [联系邮箱](mailtoلطريقة_التواصلай slaveryhere@outlook.com)。
SDK 是一个静态库,支持其他平台如 Xamarin,并与 i386、x86_64、armv7、arm64 架构完全兼容。
注意
产品已更名为 payleven Point Pay SDK,文档或类中的任何引用都与此 payleven Point Pay SDK 相关。
将以下文件拖入您的 Xcode 项目中。
PaylevenSDK.framework
AdyenToolkit.framework
AdyenToolkit.bundle
打开您的目标的 编译阶段 并将以下框架添加到 与二进制链接的库 部分
CoreData.framework
CoreLocation.framework
ExternalAccessory.framework
SystemConfiguration.framework
libsqlite3.0.dylib
AVFoundation.framework
AudioToolbox.framework
打开您的目标的 编译设置 并将 -ObjC
标志添加到其他链接器标志
将 PaylevenSDK 导入到您的文件中
#import <PaylevenSDK/PaylevenSDK.h>
打开 Info.plist 并添加以下条目
CFBundleDisplayName
com.adyen.bt1
的 UISupportedExternalAccessoryProtocols
NSLocationWhenInUseUsageDescription
或NSLocationAlwaysUsageDescription
,对于iOS 7:使用带有用户位置使用描述信息的NSLocationUsageDescription
。 <dict>
<key>NSExceptionDomains</key>
<dict>
<key>payleven.de</key>
<dict>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>
在将iOS应用程序提交到iTunes Store之前,Apple要求注册所有与经过批准的MFi设备通信的iOS应用程序。此注册过程正式将您的应用程序与payleven卡读卡器相关联,可以由payleven完成。一旦您的应用程序(捆绑ID)已注册,未来的应用程序版本将不再需要额外注册。请联系[email protected]获取提交帮助。
要获取连接的设备、开始或退款,您必须登录到payleven SDK。使用从payleven收到的API密钥,连同您的payleven商户账户(电子邮件地址和密码)对应用程序进行验证。提示:查看我们的示例演示,了解如何使用键值观察(Key-Value Observing)轻松观察登录状态。
- (void)loginWithUserName:(NSString *)username password:(NSString *)password {
__weak typeof(self) weakSelf = self;
[self.manager.payleven loginWithUsername:username password:password APIKey:self.manager.APIKey completionHandler:^(NSError *error) {
__strong typeof(weakSelf)strongSelf = weakSelf;
if([strongSelf.delegate conformsToProtocol:@protocol(PSLoginDelegate)]) {
if(error) {
[strongSelf.delegate loginDidFailWithError:error];
} else {
[strongSelf.delegate loginViewControllerDidFinish:(PSLoginViewController *)strongSelf.delegate];
}
}
}];
}
在开始集成和测试之前,请确保您已将卡读卡器配对到iOS设备上的蓝牙设置中。
一旦创建了一个PLVPayleven
实例,您需要选择卡读卡器以处理支付。请记住,每次您开始新的会话时都要选择设备。
//You probably want to visualize the devices in a UITableView
NSArray * pairedDevices = self.manager.payleven.devices;
//Get the selected device from the list
PLVDevice *device = self.sortedDevices[indexPath.row];
NSString * deviceName = device.name;
选择设备后,需要准备它以接受支付。我们将为您运行所有必要的准备和安全检查。您只需按照以下内容进行操作。此外,在触发新的支付之前,您应该始终检查您的PLVDevice对象返回的ready是否为真。
dispatch_time_t dispatchTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.00 * NSEC_PER_SEC));
__weak typeof(self)weakSelf = self;
dispatch_after(dispatchTime, dispatch_get_main_queue(), ^{
__strong typeof(weakSelf)strongSelf = weakSelf;
[device prepareWithCompletionHandler:^(NSError *error) {
if (device.ready) {
[strongSelf didSuccessfullyPrepareDevice:device controller:strongSelf];
} else {
[strongSelf didFailConfiguringDeviceWithError:error controller:strongSelf];
}
}];
});
初始化实际的支付请求。出于安全考虑,您必须在PaymentRequest中提供用户当前的位置。标识符参数允许您在将来为可能的退款引用此特定的支付。我们强烈建议您将此值保存在您的后端。
//Here we are using an arbitrary location. In your app you must provide the user's current location
CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(52.5243700, 13.4105300);
NSLocale* locale = [NSLocale currentLocale];
NSDecimalNumber* amount = [NSDecimalNumber decimalNumberWithString:@"1.00" locale:locale];
PLVPaymentRequest* request = [[PLVPaymentRequest alloc] initWithIdentifier:@"anArbitraryUniqueIdentifier"
amount:amount
currency:@"EUR"
coordinate:coordinate];
//Hint: the corresponding delegate is PLVPaymentTaskDelegate
self.paymentTask = [self.manager.payleven paymentTaskWithRequest:request device:self.device delegate:self]
if (self.paymentTask == nil) {
//Could not create Payment
} else {
[self.paymentTask start];
}
实现PLVPaymentTaskDelegate的方法以响应用户签名请求等支付事件。
- (void)paymentTask:(PLVPaymentTask *)paymentTask
needsSignatureWithCompletionHandler:(void (^)(BOOL, CGImageRef))completionHandler {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UINavigationController *navigationController
= [storyboard instantiateViewControllerWithIdentifier:@"SignatureConfirmationNavigationController"];
SignatureConfirmationViewController *signatureConfirmationViewController
= (SignatureConfirmationViewController *)navigationController.topViewController;
//Get Payer's signature and return using completionBlock (See our Sample App for full implementation)
UIImage * signature = ...
completionHandler(true, signature.CGImage);
}
可选的,您可以通过实现下面的progressDidChange方法提供更全面的用户体验。
-(void)paymentTask:(PLVPaymentTask *)paymentTask progressDidChange:(PLVPaymentProgressState)progressState
{
NSString *progressStateDescriptor;
switch (progressState) {
case PLVPaymentProgressStateNone:
progressStateDescriptor = @"None";
break;
case PLVPaymentProgressStateStarted:
progressStateDescriptor = @"Started";
break;
case PLVPaymentProgressStateRequestInsertCard:
progressStateDescriptor = @"Please insert card";
break;
case PLVPaymentProgressStateRequestPresentCard:
progressStateDescriptor = @"Please present card";
break;
case PLVPaymentProgressStateCardInserted:
progressStateDescriptor = @"Card inserted";
break;
case PLVPaymentProgressStateRequestEnterPin:
progressStateDescriptor = @"Please enter Pin";
break;
case PLVPaymentProgressStatePinEntered:
progressStateDescriptor = @"Pin entered";
break;
case PLVPaymentProgressStateContactlessBeepFailed:
progressStateDescriptor = @"Contactless Tap failed";
break;
case PLVPaymentProgressStateContactlessBeepOk:
progressStateDescriptor = @"Contactless Tap Ok";
break;
case PLVPaymentProgressStateRequestSwipeCard:
progressStateDescriptor = @"Please swipe card";
break;
default:
break;
}
//Display progressStateDescriptor to your user
}
注意
当需要进行非接触式(NFC)交易时,成功触碰卡片的标志是在payleven plus读卡器上四个(绿色)LED灯亮起,随后卡读器显示屏上会有确认信息,紧接着会有一声短促的手机设备蜂鸣声。请确保手机设备已开启音量,以便进行音频确认。
当支付任务完成时,会调用paymentTaskDidFinish:和paymentTask:didFailWithError:。您需要实现这两个方法,并将支付结果展示给用户。
- (void)paymentTaskDidFinish:(PLVPaymentTask *)paymentTask {
//Check paymentTask's result and inform the user
self.paymentTask = nil;
}
- (void)paymentTask:(PLVPaymentTask *)paymentTask didFailWithError:(NSError *)error {
//Error handling
self.paymentTask = nil;
}
您可以通过Point Pay SDK部分或全部地执行退款。首先,创建一个PLVRefundRequest。它用于创建或生成将由PLVRefundTask实例后来执行的退款请求。对于退款,您需要以下信息:
PLVRefundRequest *request = [[PLVRefundRequest alloc]initWithIdentifier:refundIdentifier
paymentIdentifier:originalPaymentId
amount:amount
currency:@"EUR"
refundDescription:@"Customer request"];
- (PLVRefundTask *)refundTaskWithRequest:(PLVRefundRequest *)request
completionHandler:(void (^)(PLVRefundResult *result, NSError *error))completionHandler;
初始化PLVRefundRequest成功后,您可以根据下面的说明触发退款。
- (void)performRefundTask {
NSDecimalNumber *amount = [PSPriceDecimal decimalForIntWithMantissa:self.currentAmount.intValue];
NSString *refundIdentifier = self.manager.randomString;
PLVRefundRequest *request = [[PLVRefundRequest alloc]initWithIdentifier:refundIdentifier
paymentIdentifier:self.externalIdTextField.text
amount:amount
currency:self.manager.currency
refundDescription:nil];
__weak typeof(self)weakSelf = self;
__strong typeof(weakSelf)strongSelf = weakSelf;
self.refundTask = [self.manager.payleven refundTaskWithRequest:request completionHandler:^(PLVRefundResult *result, NSError *error) {
if(error){
//Inform user about error
} else {
//Inform user about success
}
}];
[self.refundTask start];
}
此外,SDK还发行了销售和退款支付的收据图片,其中包含最少的收据详情。请记住,要扩展该图片,添加商家的名称、地址和相关收据ID。如果您想使用原始支付数据创建自己的收据,请联系 [email protected]。
self.receiptGenerator = paymentTask.result.receiptGenerator;
CGFloat scale = [UIScreen mainScreen].scale;
[self.receiptGenerator generateReceiptWithWidth:(384.0 * scale)
fontSize:(16.0 * scale)
lineSpacing:(8.0 * scale)
padding:(20.0 * scale)
completionHandler:
^(CGImageRef receipt) {
CGFloat scale = [UIScreen mainScreen].scale;
UIImage *image = [UIImage imageWithCGImage:receipt scale:scale orientation:UIImageOrientationUp];
self.receiptGenerator = nil;
}];
Point Pay SDK包含一个示例应用,演示了如何集成SDK。
注意
- 位置是硬编码的,需要根据用户的当前位置进行更改。
- 示例应用的Bundle ID已注册,并唯一关联到项目中使用的API密钥。如果您将API密钥更改为在开发者注册期间从payleven获得的API密钥,请记住也要将Bundle ID更改为您已注册的ID。
下面的示例集成演示了以下内容:
#import <PaylevenSDK/PLVPaymentProgressViewController.h>
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:YES];
//Init
self.paymentProgressViewController = [[PLVPaymentProgressViewController alloc]init];
[self addChildViewController:self.paymentProgressViewController];
//Set size
self.paymentProgressViewController.view.frame = self.paymentProgressContainerView.bounds;
//Add
[self.paymentProgressContainerView addSubview:self.paymentProgressViewController.view];
[self.paymentProgressViewController didMoveToParentViewController:self];
}
-(void)paymentTask:(PLVPaymentTask *)paymentTask progressDidChange:(PLVPaymentProgressState)progressState
{
if (self.paymentProgressViewController) {
[self.paymentProgressViewController animateWithPaymentProgressState:progressState];
}
}