Wibmo SDK 集成(iOS)
本文档描述了将 Wibmo SDK 集成到您的 iOS 应用程序中的步骤,以使用 PayZapp 平台进行 IAP(应用内支付)。
重要
您必须有一个 PayZapp 钱包商户账号才能使用应用内支付服务。
系统要求
为了将 PayZapp 集成到您的 iOS 应用中,您需要以下内容:
- 访问 WibmoSdk
- 商户 ID,商户 App ID 和 哈希密钥,从 PayZapp UAT/生产环境获取。
- 此文档和示例应用程序。
- 最新版本 3.1.5 可通过 Cocoapods 获取。该 SDK 与 Xcode 13.2.1 和 Cocoapods 版本 1.10.2 兼容。
将 Wibmo SDK 添加为 iOS 应用依赖
Cocoa pod(推荐)
- 在您的项目 podfile 中,在您的 App 目标下包含 pod 'wibmo-sdk’。
- 然后执行 pod install。
然后
- 将 URL 方案添加到您的项目 Info.plist 文件中。
注意: 商家 ID 在不同的配置环境中是不同的。例如,它在生产和 UAT 环境中是不同的。
用法
- 在 ViewController 中导入 WibmoSDK
- 在 AppDelegate 的方法中包含,并发布适当的通知。
- (BOOL)application:(UIApplication *)iApplication openURL:(NSURL *)iURL sourceApplication:(NSString *)iSourceApplication
annotation:(id)iAnnotation {
if (iURL && [[iURL scheme] isEqualToString:@"pz81516121"]) {
[[NSNotificationCenter defaultCenter] postNotificationName:PROCESS_INAPP_PAYMENT object:[iURL absoluteString]];
}
return YES;
}
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)iURL {
if (iURL && [[iURL scheme] isEqualToString:@"pz123456789"]) {
[[NSNotificationCenter defaultCenter] postNotificationName:PROCESS_INAPP_PAYMENT object:[iURL absoluteString]];
}
return YES;
}
注意: 对于支持 iOS 9 及以上版本的应用,请使用以下方法。
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
if (iURL && [[iURL scheme] isEqualToString:@"pz123456789"]) {
[[NSNotificationCenter defaultCenter] postNotificationName:PROCESS_INAPP_PAYMENT object:[iURL absoluteString]];
}
return YES;
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
if url.scheme == "pz123456789" {
NotificationCenter.default.post(name: Notification.Name(rawValue: kAppIAPProcessNotification), object: url.absoluteString)
}
return true
}
- 要发起付款,执行以下操作:
- 通过捕获相关细节(如交易金额、商户 App 数据、txnType(WPay/W2fa))来生成消息散列。
- 初始化 WSMerchantInfo
- 初始化 WibmoSDK 并设置代理和数据源
- 调用 performIAPTransactionFrom api 初始化交易。
注意: objc performIAPTransaction(from:)
此方法应在主线程上调用。
WSTransactionInfo *transactionInfo = [[WSTransactionInfo alloc] initWithMsgHash:messageHash[@"msgHash"] txnCurrency:kTxnCurrencyCode chargeLater:YES merAppData:merchantAppData merTxnId:messageHash[@"merTxnId"] restrictedPaymentType:@[WSPaymentOption.kPaymentOptionNone] txnAmtKnown:NO merDataField:@"Merchant Data" supportedPaymentType:@[WSPaymentOption.kPaymentOptionAllCards] txnDate:messageHash[@"txnDate"] txnDesc:@"Transaction from sample merchant for rupee 1" txnAmount:self.amount.text];
self.paymentSdk = [[WibmoSDK alloc] initWithTransactionDetails:transactionInfo datasource:self delegate:self];
[self.paymentSdk performIAPTransactionFrom:self];
let transactionInfo = WSTransactionInfo(msgHash: msgHash, txnCurrency: "356", chargeLater: chargeLater.isOn, merAppData: "AppDATA", merTxnId: txnId, restrictedPaymentType: [WSPaymentOption.kPaymentOptionNone], txnAmtKnown: amountKnown.isOn, merDataField: "merData", supportedPaymentType: [WSPaymentOption.kPaymentOptionAllCards], txnDate: date, txnDesc: "Transaction from sample merchant for amount 1", txnAmount: amount.text!)
wibmoPaymentSdk = WibmoSDK(transactionDetails: transactionInfo, datasource: self, delegate: self)
wibmoPaymentSdk?.performIAPTransaction(from: self)
注意: WibmoSDK 会根据您的环境指向不同的 URL,例如生产或 staging。 3. 根据您的需求实现 WibmoSDK 协议(如下所示)。
例如
#pragma -mark Payment DataSource
- (enum WSBuildType)buildType {
return WSBuildTypeStaging;
}
- (enum WSIAPVersion)iapVersion {
return WSIAPVersionV2;
}
- (WSMerchantInfo * _Nonnull)merchantInfoForTransaction:(WSTransactionInfo * _Nonnull)transaction {
WSMerchantInfo *merchantInfo = [[WSMerchantInfo alloc] initWithMerName:@"SampleMerchant" merCountryCode:@"IN" merId:@"81516121" merAppId:@"1" merUrlScheme:nil];
return merchantInfo;
}
- (WSCustomerInfo * _Nonnull)customerInfoForTransaction:(WSTransactionInfo * _Nonnull)transaction {
WSCustomerInfo *customerInfo = [[WSCustomerInfo alloc] initWithCustName:@"Guest User" custDob:@"01/01/2000" custEmail:@"[email protected]" custMobile:@"9000590005"];
return customerInfo;
}
- (BOOL)isWpayTransaction {
return self.paymentType.selectedSegmentIndex == 0;
}
- (WSCardInfo * _Nullable)cardInfoForTransaction:(WSTransactionInfo * _Nonnull)transaction {
return nil;
}
- (BOOL)requiresBillingAddressForTransaction:(WSTransactionInfo * _Nonnull)transaction {
return NO;
}
- (BOOL)requiresShippingAddressForTransaction:(WSTransactionInfo * _Nonnull)transaction {
return NO;
}
- (BOOL)requiresEmailIdForTransaction:(WSTransactionInfo * _Nonnull)transaction {
return NO;
}
extension ViewController: WSPaymentDatasource {
func requiresBillingAddressFor(transaction: WSTransactionInfo) -> Bool {
return billingAddrRequired.isOn
}
func requiresShippingAddressFor(transaction: WSTransactionInfo) -> Bool {
return shippingAddrRequired.isOn
}
func requiresEmailIdFor(transaction: WSTransactionInfo) -> Bool {
return emailIdRequired.isOn
}
func cardInfoFor(transaction: WSTransactionInfo) -> WSCardInfo? {
return nil
}
func buildType() -> WSBuildType {
return .staging //.production
}
func iapVersion() -> WSIAPVersion {
return .v2
}
func merchantInfoFor(transaction: WSTransactionInfo) -> WSMerchantInfo {
let merchantInfo = WSMerchantInfo(merName: "Sample Test Merchant", merCountryCode: "IN", merId: "81516121", merAppId: "1")
return merchantInfo
}
func customerInfoFor(transaction: WSTransactionInfo) -> WSCustomerInfo {
let customerInfo = WSCustomerInfo(custName: "Guest User", custDob: "01012000", custEmail: "[email protected]", custMobile: "9999999999")
return customerInfo
}
func isWpayTransaction() -> Bool {
return (paymentType.selectedSegmentIndex == 0)
}
}
#pragma -mark Payment Delegate
- (void)paymentFailedWithError:(NSError * _Nonnull)error {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Error" message:error.localizedDescription preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:nil];
[alert addAction:okAction];
[self presentViewController:alert animated:YES completion:nil];
}
- (void)paymentSuccessfullForTransaction:(NSDictionary<NSString *,id> * _Nonnull)transaction {
NSString *message = [NSString stringWithFormat:@"Transaction completed succesfully, Wibmo Transaction Id for reference is : %@",transaction[@"wibmoTxnId"]];
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Success" message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"Ok" style:UIAlertActionStyleDefault handler:nil];
[alert addAction:okAction];
[self presentViewController:alert animated:YES completion:nil];
}
extension ViewController: WSPaymentDelegate {
func paymentSuccessfullFor(transaction: Dictionary<String, Any>) {
let alert = UIAlertController(title: "Success", message: "Transaction compeleted succesfully.", preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)
alert.addAction(okAction)
self.present(alert, animated: true, completion: nil)
self.transactionStatus = transaction
self.transactionStatusLabel.text = transaction.description
print(transaction.description)
}
func paymentFailed(error: Error) {
let alert = UIAlertController(title: "Error", message: "Transaction failed to complete. Error: \(error.localizedDescription)", preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)
alert.addAction(okAction)
self.present(alert, animated: true, completion: nil)
print(error.localizedDescription)
}
}
注意: 错误响应字典示例
{
"resCode": "000",
"resDesc": "SUCCESS",
"status": "50020",
"pgErrorCode": "0",
"pgErrorDetail": "No Error",
"pgVoidTransactionId": "50204001", "newMerchantReferenceNo": "WPAYTXN1125398084375506", "rrn": "636510123204"
}
{
"resCode": "050",
"resDesc": "FAILURE",
"status": "50021",
"pgErrorCode": "10024",
"pgErrorDetail": "Void has already been done"
}
{
"resCode": "053",
"resDesc": "Invalid client IP in void request!"
}
重要: 错误代码和描述
代码 | 描述 |
---|---|
053 | 没有传递商家交易 ID/WibmotxnId! |
053 | 无效的商家 ID |
053 | 商家不活跃! |
053 | 在无效的客户端 IP 中请求空请求! |
051 | 内部错误 |
204 | 用户中止 |
070 | 消息散列失败 |
080 | 太早了;过一段时间再尝试 |
000 | 成功 |
050 | 失败 |
状态码和描述
代码 | 描述 |
---|---|
50020 | 成功 |
50021 | 失败 |
注意
- 您可以在GitHub仓库此处下载示例应用。
- 尤其是在示例应用中请注意,如果金额与消息哈希金额不同,那么您应该从SDK获取到消息哈希失败响应。