1. 程式人生 > >ios支付,帶本地伺服器驗證

ios支付,帶本地伺服器驗證

直接上程式碼.....
.h檔案:
  1. #import <StoreKit/StoreKit.h>
  2. @interface SDKApplePay : NSObject  <SKProductsRequestDelegate,SKPaymentTransactionObserver>{  
  3.     SKProductsRequest* _curProductRequest;  
  4.     NSMutableDictionary* _curActualProducts;  //實際可購買列表
  5.     NSString* _curAppId;  
  6.     bool receiptValid;  
  7. #if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_8_0
  8.     UIAlertView *alertViewTest;  
  9. #else
  10.     UIAlertController *alertController;  
  11. #endif
  12. }  
  13. + (SDKApplePay*) getInstance;  
  14. - (void) initSDK:(UIViewController *)viewController sdkName:(NSString *)sdkName;  
  15. - (void)requestProductsValidate:(NSDictionary*)productsDict;  
  16. - (void)requestProductsPay:(NSString*)productsDict;  
  17. @end


.mm檔案:
  1. #import "SDKApplePay.h"
  2. #import "Util.h"
  3. #import "JSCallObjectCBridge.h"
  4. #define MyServerURL @"你的伺服器網址"//伺服器請求的地址
  5. #define DebugModel @"0"    //@"sandbox" 沙盒測試  @"0" 正常購買
  6. @implementation SDKApplePay  
  7. static NSString* const SDK_IAP_PREFIX_PRODUCT=@"com.xxxx.xxxx.";  
  8. static SDKApplePay* curInstance=
    nil;  
  9. + (SDKApplePay*) getInstance  
  10. {  
  11.     if(nil==curInstance)  
  12.     {  
  13.         curInstance = [[SDKApplePay alloc] init];  
  14.     }  
  15.     return curInstance;  
  16. }  
  17. - (void)requestProductsValidate:(NSDictionary*)productsDict  
  18. {  
  19.     NSMutableSet* productsSet = [NSMutableSet set];  
  20.     for(NSString* key in productsDict)  
  21.     {  
  22.         [productsSet addObject:[NSString stringWithFormat:@"%@%@",SDK_IAP_PREFIX_PRODUCT,key]];  
  23.     }  
  24.     _curProductRequest=[[SKProductsRequest alloc] initWithProductIdentifiers:productsSet];  
  25.     _curProductRequest.delegate=self;  
  26.     [_curProductRequest start];  
  27. }  
  28. //購買時的呼叫方法
  29. - (void)requestProductsPay:(NSString*)productsDict  
  30. {  
  31.     if(nil==productsDict){  
  32.         //引數為空,呼叫違法
  33.         return;  
  34.     }  
  35.     if([SKPaymentQueue canMakePayments])  
  36.     {  
  37.         NSString* curProductIdentifier = nil;  
  38.         if(nil!=productsDict){  
  39.             curProductIdentifier = productsDict;  
  40.         }  
  41.         SKProduct* actualProduct = [_curActualProducts objectForKey:curProductIdentifier];  
  42.         SKPayment* payment = [SKPayment paymentWithProduct:actualProduct];  
  43.         [[SKPaymentQueue defaultQueue] addPayment:payment];  
  44.     }else
  45.     {  
  46.         //TODO 通知使用者無法進行購買
  47.     }  
  48. }  
  49. //-----------------override---------------
  50. - (void) initSDK:(UIViewController *)viewController sdkName:(NSString *)sdkName  
  51. {  
  52.     _curActualProducts=[[NSMutableDictionary alloc] init];  
  53.     NSMutableDictionary* mm = [[NSMutableDictionary alloc] init];  
  54.     [mm setObject:@"buy01" forKey:@"buy01"];  
  55.     [mm setObject:@"buy02" forKey:@"buy02"];  
  56.     [mm setObject:@"buy13" forKey:@"buy13"];  
  57.     [mm setObject:@"buy04" forKey:@"buy04"];  
  58.     [self requestProductsValidate:mm];  
  59.     [[SKPaymentQueue defaultQueue] addTransactionObserver:self];  
  60. }  
  61. //-----------------implements--------------
  62. - (void) productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response  
  63. {  
  64.     NSArray<SKProduct*>* productList=response.products;  
  65.     long count = productList.count;  
  66.     [_curActualProducts removeAllObjects];  
  67.     for(int i=0;i-count<0;i++)  
  68.     {  
  69.         SKProduct* curProduct = [productList objectAtIndex:i];  
  70.         [_curActualProducts setObject:curProduct forKey:curProduct.productIdentifier];  
  71.     }  
  72.     [_curProductRequest release];  
  73.     //======!!!!!購買時的呼叫方法
  74.     //[self requestProductsPay:nil];
  75. }  
  76. - (void) paymentQueue:(SKPaymentQueue *)queue removedTransactions:(NSArray<SKPaymentTransaction *> *)transactions  
  77. {  
  78.     NSLog(@"removedTransactions");  
  79. }  
  80. - (void) paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error  
  81. {  
  82.     NSLog(@"restoreCompletedTransactionsFailedWithError");  
  83.     //[self processRestoreFailed:queue error:error];
  84. }  
  85. - (void) paymentQueue:(SKPaymentQueue *)queue updatedDownloads:(NSArray<SKDownload *> *)downloads  
  86. {  
  87.     NSLog(@"updatedDownloads");  
  88. }  
  89. //購買結果發的回撥
  90. - (void) paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions  
  91. {  
  92.     NSLog(@"==[開始處理使用者交易操作]");  
  93.     for (SKPaymentTransaction *transaction in transactions)  
  94.     {  
  95.         NSLog(@"======[獲得使用者操作碼]:%d",(int)transaction.transactionState);  
  96.         switch (transaction.transactionState)  
  97.         {  
  98.             case SKPaymentTransactionStatePurchasing:  
  99.                 NSLog(@"SKPaymentTransactionStatePurchasing");  
  100.                 break;  
  101.             case SKPaymentTransactionStatePurchased:  
  102.                 //購買成功
  103.                 NSLog(@"SKPaymentTransactionStatePurchased:%@",transaction.payment.productIdentifier);  
  104.                 //進行回撥處理
  105.                 [self completeTransaction:transaction];  
  106.                 break;  
  107.             case SKPaymentTransactionStateFailed:  
  108.                 //購買失敗
  109.                 NSLog(@"SKPaymentTransactionStateFailed");  
  110.                 [self failedTransaction:transaction];  
  111.                 break;  
  112.             case SKPaymentTransactionStateRestored:  
  113.                 //已經購買過該商品
  114.                 NSLog(@"SKPaymentTransactionStateRestored");  
  115.                 [self restoreTransaction:transaction];  
  116.                 break;  
  117.             case SKPaymentTransactionStateDeferred:  
  118.                 NSLog(@"SKPaymentTransactionStateDeferred");  
  119.                 break;  
  120.             default:  
  121.                 break;  
  122.         }  
  123.     }  
  124.     NSLog(@"==[結束處理使用者交易操作!]");  
  125. }  
  126. - (void) paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue  
  127. {  
  128.     NSLog(@"removedTransactions");  
  129. }  
  130. //向伺服器請求驗證
  131. - (void) verifyReceiptFromMyServer:(SKPaymentTransaction *)transaction  
  132. {  
  133.     //初始化為合法
  134.     if (transaction.payment.productIdentifier !=nil) {  
  135.         //base64 encode the receipt data for sending
  136.         if ([transaction.transactionReceipt base64Encoding] != nil) {  
  137.             //將資料http post請求傳送到我的伺服器
  138.             NSURL* url = [NSURL URLWithString:MyServerURL];  
  139.             NSMutableURLRequest* theRequest = [NSMutableURLRequest requestWithURL:url];  
  140.             [theRequest setHTTPMethod:@"POST"];  
  141.             //修改通訊方式
  142.             NSString * productIdentifier = transaction.payment.productIdentifier;  
  143.             NSString *transactionReceiptString= nil;  
  144.             //系統IOS7.0以上獲取支付驗證憑證的方式應該改變,切驗證返回的資料結構也不一樣了。
  145. //            if([[UIDevice currentDevice].systemVersion floatValue]>=7.0){
  146. //                NSURLRequest*appstoreRequest = [NSURLRequest requestWithURL:[[NSBundle mainBundle]appStoreReceiptURL]];
  147. //                NSError *error = nil;
  148. //                NSData * receiptData = [NSURLConnection sendSynchronousRequest:appstoreRequest returningResponse:nil error:&error];
  149. //                NSLog(@"+++apple_receipt:\n%@+++",receiptData);
  150. //                //transactionReceiptString = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
  151. //                //transactionReceiptString = [receiptData base64EncodedStringWithOptions:0];
  152. //                transactionReceiptString = [self base64Encode:receiptData];
  153. //            }
  154. //            else{
  155.                 NSData * receiptData = transaction.transactionReceipt;  
  156.                 NSLog(@"+++apple_receipt:\n%@+++",receiptData);  
  157.                 //transactionReceiptString = [receiptData base64EncodedString];
  158.                 transactionReceiptString = [self base64Encode:receiptData];  
  159. //            }
  160.             NSLog(@"+++apple_receipt-base64:\n%@+++",transactionReceiptString);  
  161.             NSString *sendString = [NSString stringWithFormat:@"package_name=%@&product_id=%@&apple_receipt=\n%@&env=%@"@"com.tjyzy.dd2",productIdentifier,transactionReceiptString,DebugModel];  
  162.             NSLog(@"+++sendString:%@+++",sendString);  
  163.             [theRequest setHTTPBody:[sendString dataUsingEncoding:NSUTF8StringEncoding]];  
  164.             //傳送同步請求  因為你將使用自己的伺服器返回的資料來判斷是否成功
  165.             NSURLResponse* response = [[NSURLResponse alloc] init];  
  166.             NSError*       myerror =  [[NSError alloc] init];  
  167.             NSMutableData* receiveData = (NSMutableData *)[NSURLConnection sendSynchronousRequest:theRequest returningResponse:&response error:&myerror];  
  168.             //NSURLConnection* theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
  169.             //接收到伺服器返回的資料
  170.             NSString *receiptStatus = [[NSString alloc] initWithBytes: [receiveData mutableBytes] length:[receiveData length] encoding:NSUTF8StringEncoding];  
  171.             NSLog(@"\nreceiptStatus=%@",receiptStatus);  
  172.             NSString* str = @"\"errno\":0";  
  173.             if ([receiptStatus length]==0 || [receiptStatus isEqualToString:@""]) {  
  174.                 receiptValid = false;  
  175.             }else{  
  176.                 //轉換成二進位制資料
  177.                 NSData * data = [receiptStatus dataUsingEncoding:NSUTF8StringEncoding];  
  178.                 //解析JSON檔案 OC中自帶的方法
  179.                 NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];  
  180.                 int receivCode = [[dict objectForKey:@"errno"] intValue];  
  181.                 if(receivCode==0){  
  182.                     NSLog(@"++++伺服器通訊成功++++");  
  183.                     receiptValid = true;  
  184.                 }else{  
  185.                     NSLog(@"++++伺服器通訊失敗++++錯誤碼為:%d",receivCode);  
  186.                     receiptValid = false;  
  187.                 }  
  188.             }  
  189. //            [receiptStatus release];
  190. //            [myerror release];
  191. //            [response release];
  192.         } else {  
  193.             NSLog(@"當向伺服器傳送驗證資料時出錯!!!");  
  194.             receiptValid = false;  
  195.         }  
  196.     }  
  197.     else
  198.     {  
  199.         NSLog(@"無效的商品ID");  
  200.         receiptValid = false;  
  201.     }  
  202. }  
  203. //將NSData64位編碼
  204. - (NSString*) base64Encode:(NSData *)theData  
  205. {  
  206.     const uint8_t* input = (const uint8_t*)[theData bytes];  
  207.     NSInteger length = [theData length];  
  208.     staticchar table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";  
  209.     NSMutableData* data = [NSMutableData dataWithLength:((length + 2) / 3) * 4];  
  210.     uint8_t* output = (uint8_t*)data.mutableBytes;  
  211.     NSInteger i;  
  212.     for (i=0; i < length; i += 3) {  
  213.         NSInteger value = 0;  
  214.         NSInteger j;  
  215.         for (j = i; j < (i + 3); j++) {  
  216.             value <<= 8;  
  217.             if (j < length) {  
  218.                 value |= (0xFF & input[j]);  
  219.             }  
  220.         }  
  221.         NSInteger theIndex = (i / 3) * 4;  
  222.         output[theIndex + 0] =                    table[(value >> 18) & 0x3F];  
  223.         output[theIndex + 1] =                    table[(value >> 12) & 0x3F];  
  224.         output[theIndex + 2] = (i + 1) < length ? table[(value >> 6)  & 0x3F] : '=';  
  225.         output[theIndex + 3] = (i + 2) < length ? table[(value >> 0)  & 0x3F] : '=';  
  226.     }  
  227.     //return [[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding] autorelease];
  228.     return [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];  
  229. }  
  230. //購買成功
  231. - (void) completeTransaction: (SKPaymentTransaction *)transaction  
  232. {  
  233.     receiptValid = false;  
  234.     //進行伺服器驗證
  235.     [self verifyReceiptFromMyServer:transaction];//這個方法是內支付最重要的方法
  236.     if (receiptValid) {  
  237.         //給物品
  238.         [[JSCallObjectCBridge getInstance] applePaySuccess:transaction.payment.productIdentifier];  
  239.     } else {  
  240.         //[self failedTransaction:transaction];
  241.     }  
  242.     [[SKPaymentQueue defaultQueue] finishTransaction:transaction];  
  243. }  
  244. //購買恢復交易
  245. - (void) restoreTransaction: (SKPaymentTransaction *)transaction  
  246. {  
  247.     NSLog(@" 交易恢復處理");  
  248.     //給物品
  249.     [[JSCallObjectCBridge getInstance] applePaySuccess:transaction.payment.productIdentifier];  
  250.     [[SKPaymentQueue defaultQueue] finishTransaction:transaction];  
  251. }  
  252. //購買失敗
  253. - (void) failedTransaction: (SKPaymentTransaction *)transaction{  
  254.     NSLog(@"失敗");  
  255.     if (transaction.error.code != SKErrorPaymentCancelled)  
  256.     {  
  257.         //提示購買失敗
  258.         UIAlertView *alerView2 =  [[UIAlertView alloc] initWithTitle:@"Pay Result"
  259.                                                              message:@"Payment failed, Please try again!"
  260.                                                             delegate:nil cancelButtonTitle:NSLocalizedString(@"Close",nil) otherButtonTitles:nil];  
  261.         [alerView2 show];  
  262.         [alerView2 release];  
  263.     }  
  264.     [[SKPaymentQueue defaultQueue] finishTransaction: transaction];  
  265. }  
  266. -(void)dealloc  
  267. {  
  268.     [[SKPaymentQueue defaultQueue] removeTransactionObserver:self];//解除監聽
  269.     [super dealloc];  
  270. }  
  271. @end


PS:上面的程式碼部分,再檢視某些文章時,發現“系統IOS7.0以上獲取支付驗證憑證的方式應該改變,切驗證返回的資料結構也不一樣了”,最後通過實際專案發現支付驗證憑證採用原來的方式“transaction.transactionReceipt”即可。


使用方法:
1 在AppController.mm中進行初始化:
在函式“- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions”中
呼叫“[[SDKApplePay getInstance] initSDK:viewController sdkName:@"applepay"];“進行初始化;
2  在需要呼叫支付的部分呼叫支付程式碼:
[[SDKApplePay getInstance] requestProductsPay:appleProductId];  支付道具的id(appleProductId的值)例:com.xxxx.xxxx.buy01
這個id是你在蘋果後臺申請的id。

相關推薦

ios支付本地伺服器驗證

直接上程式碼..... .h檔案: #import <StoreKit/StoreKit.h>@interface SDKApplePay : NSObject  <SKProductsRequestDelegate,SKPaymentTransacti

最近在做支付支付本地測試一切正常上傳到服務器就遇到報錯:

-1 tail 服務 war tar nbsp 百度 nature function 最近在做支付寶支付,在本地測試一切正常,上傳到服務器就遇到報錯: Warning: openssl_sign() [function.openssl-sign]: Unknown sign

xcode 7.0後網路載入失敗以及本地伺服器資源載入失敗解決

在專案的info.plist 中新新增一項為NSAppTransportSecurity 型別為Dictionary 點選這一項,注意該項箭頭向下時新新增子項 NSAllowsArbitraryLoads ,型別為BOOL 型別, 值為YES

微信小程序支付java源碼

項目 event fine 監聽 java源碼 ide otto area 也有 先說下這個的背景吧。。。 本人是做java後端的,自認為還有很大的發展空間(嘻嘻,你懂的),看過一段時間的小程序可是沒有支付成功。。。最近公司要做小程序項目,老大讓我看

Unity內IAP支付二次驗證/伺服器驗證————最白話手把手教你做系列。

之前的一篇寫了Unity支付的IAP支付接入。 後來就出現了一些問題,資料統計的時候出現大量購買訂單。但是實際上賬戶的錢卻沒有增加。@¥……&¥……*@¥&@初步判定可能存在部分使用者通過其他渠道刷單的現象,然後才有以下操作,驗證使用者的訂單是

iOS啟動圖-從網絡獲取的gif圖本地一直是沒有動畫還模糊的

ads dad microsoft view text isequal sof nload conn 背景介紹:APP啟動頁,常有靜態圖加鏈接,gif加鏈接,短視頻等幾種形式。我們APP前期只有靜態圖這一種,功能已經實現。之後,有了添加gif的需求,按理說,只要添加一個類型

支付支付】掃碼付和app支付回調驗證簽名失敗問題

界面 排序 div nbsp 參數 解碼 app支付 bsp api 在檢查了參數排序,編碼解碼,文件編碼等問題後,發現還是簽名失敗,最後找出原因: 掃碼付和app支付采用的支付寶公鑰不一樣 Pid和公鑰管理裏面: 開放平臺密鑰界面和開放平臺應用界面的密鑰應該一致,

nginx功能之一可以啟動一個本地伺服器通過配置server_name和root目錄等來訪問目標檔案

  一. 下載 http://nginx.org/   下載後解壓   二. 修改配置檔案 nginx配置檔案在 nginx-1.8.0\conf\nginx.conf http { #壓縮html

利用github和git命令本地專案共享到伺服器

一、步驟   1. 建立專案根目錄 mkdir 資料夾名   2. 初始化資料夾 git init   3. 配置使用者名稱和郵箱(第一次配置後,不需要再登入) git config user.name 名字 git config user.email 郵箱

html檔案直接可以瀏覽器開啟為什麼很多人選擇本地伺服器localhost開啟?有什麼不一樣嗎?

最直接的區別,很容易注意到,一個是file協議,另一個是http協議。 --file協議更多的是將該請求視為一個本地資源訪問請求,和你使用資源管理器開啟是一樣的,是純粹的請求本地檔案。 --http請求方式則是通過假架設一個web伺服器,解析http協議的請求然後向瀏覽器返回資源資訊。我

微信支付非同步回撥你解決微信支付的深坑

1.首先我們先下載微信支付的伺服器端demo 2.個檔案作用介紹 index.jsp  下單  payRequest.jsp  獲取微信支付prepay_id等。 重點我說說這個payNotifyUrl.jsp

iOS上傳影象到伺服器以及伺服器PHP接收的幾種方法

iOS上傳影象到伺服器,以及伺服器PHP接收的幾種方法 1. 將圖片轉換為Base64編碼,POST上傳。PHP將Base64解碼為二進位制,再寫出檔案。缺點:不能上傳較大的圖片 // iOS(Swift) func upload(image: UIImage, url: S

關於專案本地執行未亂碼上傳伺服器專案亂碼

如果是直接用其他編輯器(如visualCode、sublime等)寫的前端頁面。可能匯入myeclipse時,未在jsp頭部加上jsp頭部。 <%@ page language="java" import="java.util.*" pageEncoding="utf8"%> <

用nodejs搭建一個本地伺服器以供本地介面獲取服務端資料

1、首先下載安裝好nodejs 64位的nodejs5.6.0下載地址:  5.6.0 nodejs,根據提示安裝在自己的電腦上即可 2、安裝好了,開啟cmd視窗,輸入命令:npm -v 檢驗nodejs是否安裝成功,如果出現以下介面則說明安裝成功了 3、輸入命令 

python程式碼本地執行不報錯上傳伺服器後報錯???

本地執行是成功的,程式碼也更新了,但在伺服器上執行程式碼就報錯了,500 Internal Server ErrorThe server encountered an internal error and was unable to complete your request. Either t

資料庫部署到linux伺服器本地訪問。

1.  將本地的sql檔案上傳至伺服器   scp /Users/fangke/Documents/article.sql [email protected]:/usr/local 2. 登陸伺服器的mysql   3. 建立資料庫   4. 執行

spring boot 讀取本地伺服器/本地硬碟上的圖片避免圖片放在tomcat等伺服器下,windows系統為例

圖片放在主體專案所在伺服器以外的好處不言而喻,這裡以windows系統的E盤為例,E盤根目錄下放一張圖片,"test.jpg". 在後臺放置這樣一個類: import org.springframework.context.annotation.Configuration

【已解決】iphone 登出賬號的時候報錯:驗證失敗連線到伺服器時出現問題

iphone 登出賬號的時候報錯:驗證失敗,連線到伺服器時出現問題,如下 在網上查了半天一點都沒有用 最後撥打的蘋果熱線,原來是蘋果的網路許可權的問題,預設的是把“設定”應用的網路關閉的,只需要把網路裡面“設定”這個應用的網路允許“WLAN與蜂窩行動網路”。 第

IP地址正則表示式*驗證

IP地址正則表示式,在網上找了很多,但是沒有看到帶 ‘ * ’ 的正則表示式,通常我們在設定IP時,會設定IP段(0-255)或者用 ‘ * ’ 代替。  1、下為不帶 ‘ * ’ 的正則表示式 var checkName = /^(?:(?:1[0-9][0-9]\.)|

【微信小程式控制硬體②】 開始微信小程式之旅匯入小程式Mqtt客戶端原始碼實現簡單的驗證和通訊於伺服器!(附帶原始碼)

本博文由熱愛分享熱愛技術的半顆心臟原創,非官方人員、非組織名義編寫,博文如有不對或侵犯您的權益,請及時留言,第一時間糾正! 一、前言; 繼續我們的小程式控制智慧硬體(包括esp8266)學