主要做一些轉(zhuǎn)載 備注在自己的簡(jiǎn)書里面几晤。
每篇文章都注明轉(zhuǎn)載
本文章轉(zhuǎn)載?http://www.reibang.com/p/f7bff61e0b31
項(xiàng)目中使用到了中間貨幣(金幣)的形式來進(jìn)行功能使用,模式是使用RMB換成-金幣比如:(1RMB = 10金幣),所以會(huì)集成第三方的支付平臺(tái),使用了微信和支付寶的第三方平臺(tái)過后,發(fā)現(xiàn)審核失敗,被蘋果拒絕,查了一查原因,才是因?yàn)樘O果對(duì)app內(nèi)的中間幣的購買必須走蘋果內(nèi)購(比如沖點(diǎn)券,比如買鉆石....)古话。所以無奈只有使用蘋果內(nèi)購,由于蘋果內(nèi)購的步驟很多,設(shè)置的東西太多,所以將這步驟記錄下來。
首先設(shè)置協(xié)議
1.打開itunes Connect,選擇協(xié)議哥蔚,稅務(wù)和銀行業(yè)務(wù)
image.png
2.點(diǎn)擊Request Contracts(申請(qǐng)合同)下面的,request,點(diǎn)了幾個(gè)確定和下一步后回到主界面舵匾。
image.png
Contact info:聯(lián)系人信息
Bank info:銀行信息
Tax info:稅務(wù)信息
image.png
3.首先設(shè)置聯(lián)系人信息,點(diǎn)擊Contact info下面的 Set up(設(shè)置),點(diǎn)擊Add New Contract(增加先的聯(lián)系方式)
image.png
4.填寫詳情
填寫完成后點(diǎn)擊save(保存)
image.png
5.在下面的所有項(xiàng)目中都選擇剛剛填寫的信息,選擇后點(diǎn)擊右下角的done(完成)诡曙,你可以創(chuàng)建很多聯(lián)系人,在不同的職務(wù)選擇不同的聯(lián)系人。因?yàn)槲沂仟?dú)立開發(fā),所以我全部填寫的我自己笆豁。
Senior Management:高管
Financial:財(cái)務(wù)
Technical:技術(shù)支持
Legal:法務(wù)
Marketing:市場(chǎng)推廣
image.png
6.設(shè)置銀行信息,點(diǎn)擊Back info下面的Set up,彈出頁面
點(diǎn)擊Add Bank Account(添加銀行賬號(hào))
image.png
選擇china,后點(diǎn)擊next郎汪。
image.png
填寫了CNAPS Code后點(diǎn)擊Next
image.png
會(huì)彈出你的銀行卡開戶地的信息,確認(rèn)一下點(diǎn)擊next
image.png
填寫銀行卡信息赤赊,注意:戶主名只能寫拼音,比如:李三(Li San)。填完后點(diǎn)擊Next
image.png
彈出確定信息頁面煞赢,在下面打鉤后點(diǎn)擊Save
image.png
點(diǎn)擊了save后就可以在彈出的頁面中選擇剛剛填寫的卡了抛计。選擇后點(diǎn)擊Save
image.png
7.設(shè)置稅務(wù)信息,點(diǎn)擊Tax info下面的Set up,此時(shí)聯(lián)系人信息已經(jīng)變成可以編輯狀態(tài),銀行信息為瀏覽狀態(tài)耕驰。
image.png
彈出的界面中,稅務(wù)分為三種
U.S Tax Forms: 美國稅務(wù)
Australia Tax Forms:澳大利亞稅務(wù)
Canada Tax Forms: 加拿大稅務(wù)
這里我選擇的美國稅務(wù),就是第一個(gè)
image.png
彈出第一個(gè)選擇,點(diǎn)擊submit(提交)后,彈出第二個(gè)選擇
image.png
彈出第二個(gè)選擇,選擇后點(diǎn)擊submit
image.png
彈出第三個(gè)頁面爷辱,填寫的資料后點(diǎn)擊提交,記得勾選頁面上的幾個(gè)復(fù)選框
image.png
在提交成功后,狀態(tài)就變成processing成功
image.png
到這里設(shè)置的協(xié)議就已經(jīng)設(shè)置完了。
創(chuàng)建項(xiàng)目的內(nèi)購
1.進(jìn)入到項(xiàng)目的APP信息頁面,點(diǎn)擊功能朦肘,在彈出的頁面點(diǎn)擊App內(nèi)購買項(xiàng)目后面的?。
image.png
2.在彈出的新對(duì)話框中選擇你需要哪一種服務(wù)双饥,由于我的項(xiàng)目需要兌換成消耗的金幣,所以我選擇第一個(gè)媒抠。選擇后點(diǎn)擊創(chuàng)建。
image.png
3.開始填寫內(nèi)購項(xiàng)目信息咏花。填完后點(diǎn)擊右上角的存儲(chǔ)(所有信息必須填寫完整)趴生。
image.png
4.點(diǎn)擊存儲(chǔ)后,內(nèi)購列表就會(huì)有剛剛創(chuàng)建的內(nèi)購條目昏翰。
image.png
你app有幾個(gè)內(nèi)購級(jí)別就需要依次創(chuàng)建幾個(gè)條目苍匆。
添加測(cè)試賬號(hào),用來測(cè)試支付功能
1.點(diǎn)擊圖中用戶和職能
image.png
2.點(diǎn)擊沙盒測(cè)試員,然后點(diǎn)擊左邊的?按鈕。
image.png
3.設(shè)置好信息點(diǎn)擊右上角存儲(chǔ)就可以,記住里面的郵箱和密碼用于支付的時(shí)候登陸Apple id
image.png
代碼集成
打開自己的項(xiàng)目,創(chuàng)建一個(gè)測(cè)試類棚菊。代碼都有注釋和步驟,直接上代碼浸踩。
注意:
1.必須用真機(jī)測(cè)試。
2.測(cè)試的時(shí)候必須退出自己的apple ID统求。彈出頁面后登陸沙盒的測(cè)試apple id检碗。
#import "TestPayController.h"
// 1.首先導(dǎo)入支付包
#import
// 2.設(shè)置代理服務(wù)
@interface TestPayController ()
@end
@implementation TestPayController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
//3.創(chuàng)建測(cè)試按鈕
UIButton *testBtn = [[UIButton alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
testBtn.backgroundColor = [UIColor redColor];
[testBtn addTarget:self action:@selector(clickTestBtnAction) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:testBtn];
// 4.設(shè)置支付服務(wù)
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
}
//點(diǎn)擊測(cè)試按鈕
- (void)clickTestBtnAction
{
// 5.點(diǎn)擊按鈕的時(shí)候判斷app是否允許apple支付
//如果app允許applepay
if ([SKPaymentQueue canMakePayments]) {
NSLog(@"yes");
// 6.請(qǐng)求蘋果后臺(tái)商品
[self getRequestAppleProduct];
}
else
{
NSLog(@"not");
}
}
//請(qǐng)求蘋果商品
- (void)getRequestAppleProduct
{
// 7.這里的com.czchat.CZChat01就對(duì)應(yīng)著蘋果后臺(tái)的商品ID,他們是通過這個(gè)ID進(jìn)行聯(lián)系的。
NSArray *product = [[NSArray alloc] initWithObjects:@"com.czchat.CZChat01",nil];
NSSet *nsset = [NSSet setWithArray:product];
// 8.初始化請(qǐng)求
SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:nsset];
request.delegate = self;
// 9.開始請(qǐng)求
[request start];
}
// 10.接收到產(chǎn)品的返回信息,然后用返回的商品信息進(jìn)行發(fā)起購買請(qǐng)求
- (void) productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
NSArray *product = response.products;
//如果服務(wù)器沒有產(chǎn)品
if([product count] == 0){
NSLog(@"nothing");
return;
}
SKProduct *requestProduct = nil;
for (SKProduct *pro in product) {
NSLog(@"%@", [pro description]);
NSLog(@"%@", [pro localizedTitle]);
NSLog(@"%@", [pro localizedDescription]);
NSLog(@"%@", [pro price]);
NSLog(@"%@", [pro productIdentifier]);
// 11.如果后臺(tái)消費(fèi)條目的ID與我這里需要請(qǐng)求的一樣(用于確保訂單的正確性)
if([pro.productIdentifier isEqualToString:@"com.czchat.CZChat01"]){
requestProduct = pro;
}
}
// 12.發(fā)送購買請(qǐng)求
SKPayment *payment = [SKPayment paymentWithProduct:requestProduct];
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
//請(qǐng)求失敗
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error{
NSLog(@"error:%@", error);
}
//反饋請(qǐng)求的產(chǎn)品信息結(jié)束后
- (void)requestDidFinish:(SKRequest *)request{
NSLog(@"信息反饋結(jié)束");
}
// 13.監(jiān)聽購買結(jié)果
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transaction{
for(SKPaymentTransaction *tran in transaction){
switch (tran.transactionState) {
case SKPaymentTransactionStatePurchased:
NSLog(@"交易完成");
break;
case SKPaymentTransactionStatePurchasing:
NSLog(@"商品添加進(jìn)列表");
break;
case SKPaymentTransactionStateRestored:
NSLog(@"已經(jīng)購買過商品");
[[SKPaymentQueue defaultQueue] finishTransaction:tran];
break;
case SKPaymentTransactionStateFailed:
NSLog(@"交易失敗");
[[SKPaymentQueue defaultQueue] finishTransaction:tran];
break;
default:
break;
}
}
}
// 14.交易結(jié)束,當(dāng)交易結(jié)束后還要去appstore上驗(yàn)證支付信息是否都正確,只有所有都正確后,我們就可以給用戶方法我們的虛擬物品了码邻。
- (void)completeTransaction:(SKPaymentTransaction *)transaction
{
NSString * str=[[NSString alloc]initWithData:transaction.transactionReceipt encoding:NSUTF8StringEncoding];
NSString *environment=[self environmentForReceipt:str];
NSLog(@"----- 完成交易調(diào)用的方法completeTransaction 1--------%@",environment);
// 驗(yàn)證憑據(jù)折剃,獲取到蘋果返回的交易憑據(jù)
// appStoreReceiptURL iOS7.0增加的,購買交易完成后像屋,會(huì)將憑據(jù)存放在該地址
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
// 從沙盒中獲取到購買憑據(jù)
NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
/**
20? ? ? BASE64 常用的編碼方案怕犁,通常用于數(shù)據(jù)傳輸,以及加密算法的基礎(chǔ)算法己莺,傳輸過程中能夠保證數(shù)據(jù)傳輸?shù)姆€(wěn)定性
21? ? ? BASE64是可以編碼和解碼的
22? ? ? */
NSString *encodeStr = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
NSString *sendString = [NSString stringWithFormat:@"{\"receipt-data\" : \"%@\"}", encodeStr];
NSLog(@"_____%@",sendString);
NSURL *StoreURL=nil;
if ([environment isEqualToString:@"environment=Sandbox"]) {
StoreURL= [[NSURL alloc] initWithString: @"https://sandbox.itunes.apple.com/verifyReceipt"];
}
else{
StoreURL= [[NSURL alloc] initWithString: @"https://buy.itunes.apple.com/verifyReceipt"];
}
//這個(gè)二進(jìn)制數(shù)據(jù)由服務(wù)器進(jìn)行驗(yàn)證奏甫;zl
NSData *postData = [NSData dataWithBytes:[sendString UTF8String] length:[sendString length]];
NSLog(@"++++++%@",postData);
NSMutableURLRequest *connectionRequest = [NSMutableURLRequest requestWithURL:StoreURL];
[connectionRequest setHTTPMethod:@"POST"];
[connectionRequest setTimeoutInterval:50.0];//120.0---50.0zl
[connectionRequest setCachePolicy:NSURLRequestUseProtocolCachePolicy];
[connectionRequest setHTTPBody:postData];
//開始請(qǐng)求
NSError *error=nil;
NSData *responseData=[NSURLConnection sendSynchronousRequest:connectionRequest returningResponse:nil error:&error];
if (error) {
NSLog(@"驗(yàn)證購買過程中發(fā)生錯(cuò)誤,錯(cuò)誤信息:%@",error.localizedDescription);
return;
}
NSDictionary *dic=[NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingAllowFragments error:nil];
NSLog(@"請(qǐng)求成功后的數(shù)據(jù):%@",dic);
//這里可以等待上面請(qǐng)求的數(shù)據(jù)完成后并且state = 0 驗(yàn)證憑據(jù)成功來判斷后進(jìn)入自己服務(wù)器邏輯的判斷,也可以直接進(jìn)行服務(wù)器邏輯的判斷,驗(yàn)證憑據(jù)也就是一個(gè)安全的問題篇恒。樓主這里沒有用state = 0 來判斷扶檐。
//? [[SKPaymentQueue defaultQueue] finishTransaction: transaction];
NSString *product = transaction.payment.productIdentifier;
NSLog(@"transaction.payment.productIdentifier++++%@",product);
if ([product length] > 0)
{
NSArray *tt = [product componentsSeparatedByString:@"."];
NSString *bookid = [tt lastObject];
if([bookid length] > 0)
{
NSLog(@"打印bookid%@",bookid);
//這里可以做操作吧用戶對(duì)應(yīng)的虛擬物品通過自己服務(wù)器進(jìn)行下發(fā)操作,或者在這里通過判斷得到用戶將會(huì)得到多少虛擬物品,在后面([self getApplePayDataToServerRequsetWith:transaction];的地方)上傳上面自己的服務(wù)器。
}
}
//此方法為將這一次操作上傳給我本地服務(wù)器,記得在上傳成功過后一定要記得銷毀本次操作胁艰。調(diào)用[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
[self getApplePayDataToServerRequsetWith:transaction];
}
//結(jié)束后一定要銷毀
- (void)dealloc
{
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
-(NSString * )environmentForReceipt:(NSString * )str
{
str= [str stringByReplacingOccurrencesOfString:@"\r\n" withString:@""];
str = [str stringByReplacingOccurrencesOfString:@"\n" withString:@""];
str = [str stringByReplacingOccurrencesOfString:@"\t" withString:@""];
str=[str stringByReplacingOccurrencesOfString:@" " withString:@""];
str=[str stringByReplacingOccurrencesOfString:@"\"" withString:@""];
NSArray * arr=[str componentsSeparatedByString:@";"];
//存儲(chǔ)收據(jù)環(huán)境的變量
NSString * environment=arr[2];
return environment;
}
@end
注意:在需要修改已經(jīng)上線的內(nèi)購的時(shí)候需要重新創(chuàng)建新的內(nèi)購條目,然后重新提交款筑。
作者:Chaman_Elephant
鏈接:http://www.reibang.com/p/f7bff61e0b31
來源:簡(jiǎn)書
著作權(quán)歸作者所有智蝠。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處奈梳。