您的位置:首页 > 移动开发 > IOS开发

iOS支付(含服务器验证)

2016-12-19 10:32 811 查看
直接上代码.....

.h文件:
#import <StoreKit/StoreKit.h>

@interface SDKApplePay : NSObject  <SKProductsRequestDelegate,SKPaymentTransactionObserver>{
SKProductsRequest* _curProductRequest;
NSMutableDictionary* _curActualProducts;  //实际可购买列表
NSString* _curAppId;
bool receiptValid;

#if __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_8_0
UIAlertView *alertViewTest;
#else
UIAlertController *alertController;
#endif

}

+ (SDKApplePay*) getInstance;

- (void) initSDK:(UIViewController *)viewController sdkName:(NSString *)sdkName;
- (void)requestProductsValidate:(NSDictionary*)productsDict;
- (void)requestProductsPay:(NSString*)productsDict;

@end


.mm文件:
#import "SDKApplePay.h"
#import "Util.h"
#import "JSCallObjectCBridge.h"

#define MyServerURL @"你的服务器网址"//服务器请求的地址
#define DebugModel @"0"    //@"sandbox" 沙盒测试  @"0" 正常购买

@implementation SDKApplePay

static NSString* const SDK_IAP_PREFIX_PRODUCT=@"com.xxxx.xxxx.";

static SDKApplePay* curInstance=nil;

+ (SDKApplePay*) getInstance
{
if(nil==curInstance)
{
curInstance = [[SDKApplePay alloc] init];
}
return curInstance;
}

- (void)requestProductsValidate:(NSDictionary*)productsDict
{
NSMutableSet* productsSet = [NSMutableSet set];
for(NSString* key in productsDict)
{
[productsSet addObject:[NSString stringWithFormat:@"%@%@",SDK_IAP_PREFIX_PRODUCT,key]];
}
_curProductRequest=[[SKProductsRequest alloc] initWithProductIdentifiers:productsSet];
_curProductRequest.delegate=self;
[_curProductRequest start];
}

//购买时的调用方法
- (void)requestProductsPay:(NSString*)productsDict
{
if(nil==productsDict){
//参数为空,调用违法
return;
}
if([SKPaymentQueue canMakePayments])
{
NSString* curProductIdentifier = nil;
if(nil!=productsDict){
curProductIdentifier = productsDict;
}
SKProduct* actualProduct = [_curActualProducts objectForKey:curProductIdentifier];
SKPayment* payment = [SKPayment paymentWithProduct:actualProduct];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}else
{
//TODO 通知用户无法进行购买
}
}

//-----------------override---------------

- (void) initSDK:(UIViewController *)viewController sdkName:(NSString *)sdkName
{
_curActualProducts=[[NSMutableDictionary alloc] init];
NSMutableDictionary* mm = [[NSMutableDictionary alloc] init];
[mm setObject:@"buy01" forKey:@"buy01"];
[mm setObject:@"buy02" forKey:@"buy02"];
[mm setObject:@"buy13" forKey:@"buy13"];
[mm setObject:@"buy04" forKey:@"buy04"];

[self requestProductsValidate:mm];

[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
}

//-----------------implements--------------
- (void) productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
NSArray<SKProduct*>* productList=response.products;
long count = productList.count;
[_curActualProducts removeAllObjects];
for(int i=0;i-count<0;i++)
{
SKProduct* curProduct = [productList objectAtIndex:i];
[_curActualProducts setObject:curProduct forKey:curProduct.productIdentifier];
}
[_curProductRequest release];

//======!!!!!购买时的调用方法
//[self requestProductsPay:nil];
}

- (void) paymentQueue:(SKPaymentQueue *)queue removedTransactions:(NSArray<SKPaymentTransaction *> *)transactions
{
NSLog(@"removedTransactions");
}

- (void) paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error
{
NSLog(@"restoreCompletedTransactionsFailedWithError");
//[self processRestoreFailed:queue error:error];
}

- (void) paymentQueue:(SKPaymentQueue *)queue updatedDownloads:(NSArray<SKDownload *> *)downloads
{
NSLog(@"updatedDownloads");
}

//购买结果发的回调
- (void) paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions
{
NSLog(@"==[开始处理用户交易操作]");
for (SKPaymentTransaction *transaction in transactions)
{
NSLog(@"======[获得用户操作码]:%d",(int)transaction.transactionState);
switch (transaction.transactionState)
{
case SKPaymentTransactionStatePurchasing:
NSLog(@"SKPaymentTransactionStatePurchasing");
break;
case SKPaymentTransactionStatePurchased:
//购买成功
NSLog(@"SKPaymentTransactionStatePurchased:%@",transaction.payment.productIdentifier);
//进行回调处理
[self completeTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
//购买失败
NSLog(@"SKPaymentTransactionStateFailed");
[self failedTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
//已经购买过该商品
NSLog(@"SKPaymentTransactionStateRestored");
[self restoreTransaction:transaction];
break;
case SKPaymentTransactionStateDeferred:
NSLog(@"SKPaymentTransactionStateDeferred");
break;
default:
break;
}
}
NSLog(@"==[结束处理用户交易操作!]");
}

- (void) paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue
{
NSLog(@"removedTransactions");
}

//向服务器请求验证
- (void) verifyReceiptFromMyServer:(SKPaymentTransaction *)transaction
{
//初始化为合法
if (transaction.payment.productIdentifier !=nil) {
//base64 encode the receipt data for sending
if ([transaction.transactionReceipt base64Encoding] != nil) {
//将数据http post请求发送到我的服务器
NSURL* url = [NSURL URLWithString:MyServerURL];
NSMutableURLRequest* theRequest = [NSMutableURLRequest requestWithURL:url];

[theRequest setHTTPMethod:@"POST"];
//修改通信方式
NSString * productIdentifier = transaction.payment.productIdentifier;
NSString *transactionReceiptString= nil;

//系统IOS7.0以上获取支付验证凭证的方式应该改变,切验证返回的数据结构也不一样了。
//            if([[UIDevice currentDevice].systemVersion floatValue]>=7.0){
//                NSURLRequest*appstoreRequest = [NSURLRequest requestWithURL:[[NSBundle mainBundle]appStoreReceiptURL]];
//                NSError *error = nil;
//                NSData * receiptData = [NSURLConnection sendSynchronousRequest:appstoreRequest returningResponse:nil error:&error];
//                NSLog(@"+++apple_receipt:\n%@+++",receiptData);
//                //transactionReceiptString = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
//                //transactionReceiptString = [receiptData base64EncodedStringWithOptions:0];
//                transactionReceiptString = [self base64Encode:receiptData];
//            }
//            else{
NSData * receiptData = transaction.transactionReceipt;
NSLog(@"+++apple_receipt:\n%@+++",receiptData);
//transactionReceiptString = [receiptData base64EncodedString];
transactionReceiptString = [self base64Encode:receiptData];
//            }
NSLog(@"+++apple_receipt-base64:\n%@+++",transactionReceiptString);

NSString *sendString = [NSString stringWithFormat:@"package_name=%@&product_id=%@&apple_receipt=\n%@&env=%@", @"com.tjyzy.dd2",productIdentifier,transactionReceiptString,DebugModel];
NSLog(@"+++sendString:%@+++",sendString);
[theRequest setHTTPBody:[sendString dataUsingEncoding:NSUTF8StringEncoding]];

//发送同步请求  因为你将使用自己的服务器返回的数据来判断是否成功
NSURLResponse* response = [[NSURLResponse alloc] init];
NSError*       myerror =  [[NSError alloc] init];
NSMutableData* receiveData = (NSMutableData *)[NSURLConnection sendSynchronousRequest:theRequest returningResp
4000
onse:&response error:&myerror];

//NSURLConnection* theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];

//接收到服务器返回的数据
NSString *receiptStatus = [[NSString alloc] initWithBytes: [receiveData mutableBytes] length:[receiveData length] encoding:NSUTF8StringEncoding];
NSLog(@"\nreceiptStatus=%@",receiptStatus);
NSString* str = @"\"errno\":0";

if ([receiptStatus length]==0 || [receiptStatus isEqualToString:@""]) {
receiptValid = false;
}else{
//转换成二进制数据
NSData * data = [receiptStatus dataUsingEncoding:NSUTF8StringEncoding];
//解析JSON文件 OC中自带的方法
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
int receivCode = [[dict objectForKey:@"errno"] intValue];
if(receivCode==0){
NSLog(@"++++服务器通信成功++++");
receiptValid = true;
}else{
NSLog(@"++++服务器通信失败++++错误码为:%d",receivCode);
receiptValid = false;
}
}

//            [receiptStatus release];
//            [myerror release];
//            [response release];

} else {
NSLog(@"当向服务器发送验证数据时出错!!!");
receiptValid = false;
}
}
else
{
NSLog(@"无效的商品ID");
receiptValid = false;
}
}

//将NSData64位编码
- (NSString*) base64Encode:(NSData *)theData
{
const uint8_t* input = (const uint8_t*)[theData bytes];
NSInteger length = [theData length];

static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

NSMutableData* data = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
uint8_t* output = (uint8_t*)data.mutableBytes;

NSInteger i;
for (i=0; i < length; i += 3) {
NSInteger value = 0;
NSInteger j;
for (j = i; j < (i + 3); j++) {
value <<= 8;

if (j < length) {
value |= (0xFF & input[j]);
}
}

NSInteger theIndex = (i / 3) * 4;
output[theIndex + 0] =                    table[(value >> 18) & 0x3F];
output[theIndex + 1] =                    table[(value >> 12) & 0x3F];
output[theIndex + 2] = (i + 1) < length ? table[(value >> 6)  & 0x3F] : '=';
output[theIndex + 3] = (i + 2) < length ? table[(value >> 0)  & 0x3F] : '=';
}

//return [[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding] autorelease];
return [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
}

//购买成功
- (void) completeTransaction: (SKPaymentTransaction *)transaction

{
receiptValid = false;
//进行服务器验证
[self verifyReceiptFromMyServer:transaction];//这个方法是内支付最重要的方法
if (receiptValid) {
//给物品
[[JSCallObjectCBridge getInstance] applePaySuccess:transaction.payment.productIdentifier];
} else {
//[self failedTransaction:transaction];
}

[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
//购买恢复交易
- (void) restoreTransaction: (SKPaymentTransaction *)transaction

{
NSLog(@" 交易恢复处理");
//给物品
[[JSCallObjectCBridge getInstance] applePaySuccess:transaction.payment.productIdentifier];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
//购买失败
- (void) failedTransaction: (SKPaymentTransaction *)transaction{
NSLog(@"失败");
if (transaction.error.code != SKErrorPaymentCancelled)
{
//提示购买失败
UIAlertView *alerView2 =  [[UIAlertView alloc] initWithTitle:@"Pay Result"
message:@"Payment failed, Please try again!"
delegate:nil cancelButtonTitle:NSLocalizedString(@"Close",nil) otherButtonTitles:nil];

[alerView2 show];
[alerView2 release];
}
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
-(void)dealloc
{
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];//解除监听
[super dealloc];
}
@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支付