iOS 苹果内购详细步骤

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

本文链接:https://blog.csdn.net/qq_22080737/article/details/79786500

一、设置协议等相关

1.点击协议、税务和银行业务。

2.点击 Request Contracts 下面的 Request,一直点击直到主协议界面。

主协议界面

Contact info :联系人信息

Bank info :银行信息

Tax info :税务信息

3.点击 Contact Info 下面的Set Up,设置联系人信息,然后点击 Add New Contract,添加新的联系信息。

4.填写完整并保存。

5.选择联系人,因为我是独立开发,所以填写的自己的,如果你是多人开发,你可以添加多个联系人。

Senior Management:高级管理人员

Financial :财务

Technical :技术支持

Legal :法务

Marketing :市场推广

添加完成之后,对应选择好就行。

6.点击 Bank Info 下的 Set Up,然后点击 Add Bank Account 添加银行账号。

点击 Select One,选择 China ,点击 next。

填写 CNAPS Code,点击 next。

CNAPS Code:中国现代化支付系统代码,又叫做联行号。可以从网上查询,也可以直接点击Look up CNAPS Code进行查询,再不济,也可以直接打电话咨询相应银行客服。

点击 next,核对一下,继续 next。

填写银行卡相关信息,点击 next。(持卡人姓名,如张三(Zhang San))

确认一下,点击 save 保存。

选择对应的银行卡,点击 save。

7.点击 Tax Info 下面的 Set Up,设置税务信息。

税务分三种:

U.S Tax Forms : 美国税务

Australia Tax Forms:澳大利亚税务

Canada Tax Forms : 加拿大税务

我们选择美国税务,点击 Done。

如果没有就选择 NO,点击 Submit。

如果没有就选择 NO。

填写完整,点击 Submit。

核对信息无误后提交,状态显示 Processing 表示成功。

二、创建项目的内购条目

1.进入 APP,点击功能。

根据情况选择,我选择的第一个。

填写内购项目信息,点击存储。

下面这些信息也要填完整,否则会提示元数据丢失(坑)。

注意:你 App 有几个内购级别就需要依次创建几个条目。

三、添加沙盒测试账号

1.点击用户和职能

2.点击沙盒技术测试员

3.点击 “+” 添加测试员,邮箱和密码用于支付的时候登陆 Apple ID。

四、代码集成

#import "ApplePayVC.h"

//导入

#import <StoreKit/StoreKit.h>

//遵循代理

@interface ApplePayVC ()

<

SKPaymentTransactionObserver,

SKProductsRequestDelegate

>

//支付按钮

@property (nonatomic, strong) UIButton *payBtn;

@end

@implementation ApplePayVC

- (void)viewDidLoad

{

    [super viewDidLoad];

    [self setupPayBtn];

    //设置支付服务

    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];

}

#pragma mark - UI

- (void)setupPayBtn

{

    _payBtn = [UIButton buttonWithType:UIButtonTypeCustom];

    _payBtn.frame = CGRectMake(100, 100, 100, 100);

    _payBtn.backgroundColor = [UIColor redColor];

    [_payBtn setTitle:@"支付" forState:UIControlStateNormal];

    [_payBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];

    _payBtn.titleLabel.font = [UIFont systemFontOfSize:15.0];

    [_payBtn addTarget:self action:@selector(payBtnAction) forControlEvents:UIControlEventTouchUpInside];

    [self.view addSubview:_payBtn];

}

#pragma mark - BtnAction

- (void)payBtnAction

{

    //是否允许内购

    if ([SKPaymentQueue canMakePayments]) {

        NSLog(@"用户允许内购");

        //bundleid+xxx 就是你添加内购条目设置的产品ID

        NSArray *product = [[NSArray alloc] initWithObjects:@"bundleid+xxx",nil];

        NSSet *nsset = [NSSet setWithArray:product];

        //初始化请求

        SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:nsset];

        request.delegate = self;

        //开始请求

        [request start];

    }else{

        NSLog(@"用户不允许内购");

    }

}

#pragma mark - SKProductsRequestDelegate

//接收到产品的返回信息,然后用返回的商品信息进行发起购买请求

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response NS_AVAILABLE_IOS(3_0)

{

    NSArray *product = response.products;

    //如果服务器没有产品

    if([product count] == 0){

        NSLog(@"没有该商品");

        return;

    }

    SKProduct *requestProduct = nil;

    for (SKProduct *pro in product) {

        NSLog(@"%@", [pro description]);

        NSLog(@"%@", [pro localizedTitle]);

        NSLog(@"%@", [pro localizedDescription]);

        NSLog(@"%@", [pro price]);

        NSLog(@"%@", [pro productIdentifier]);

        //如果后台消费条目的ID与我这里需要请求的一样(用于确保订单的正确性)

        if([pro.productIdentifier isEqualToString:@"bundleid+xxx"]){

            requestProduct = pro;

        }

    }

    //发送购买请求

    SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:requestProduct];

        payment.applicationUsername = userId;//可以是userId,也可以是订单id,跟你自己需要而定

    [[SKPaymentQueue defaultQueue] addPayment:payment];

}

#pragma mark - SKRequestDelegate

//请求失败

- (void)request:(SKRequest *)request didFailWithError:(NSError *)error

{

    NSLog(@"error:%@", error);

}

//请求结束

- (void)requestDidFinish:(SKRequest *)request

{

    NSLog(@"请求结束");

}

#pragma mark - SKPaymentTransactionObserver

//监听购买结果

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions

{

    for(SKPaymentTransaction *tran in transactions){

        switch (tran.transactionState) {

            case SKPaymentTransactionStatePurchased:

                NSLog(@"交易完成");

                [self completeTransaction:tran];

                break;

            case SKPaymentTransactionStatePurchasing:

                NSLog(@"商品添加进列表");

                break;

            case SKPaymentTransactionStateRestored:

                NSLog(@"已经购买过商品");

//                [[SKPaymentQueue defaultQueue] finishTransaction:tran]; 消耗型商品不用写

                break;

            case SKPaymentTransactionStateFailed:

                NSLog(@"交易失败");

                [[SKPaymentQueue defaultQueue] finishTransaction:tran];

                break;

            default:

                break;

        }

    }

}

//交易结束,当交易结束后还要去appstore上验证支付信息是否都正确,只有所有都正确后,我们就可以给用户方法我们的虚拟物品了。

- (void)completeTransaction:(SKPaymentTransaction *)transaction

{

    // 验证凭据,获取到苹果返回的交易凭据

    // appStoreReceiptURL iOS7.0增加的,购买交易完成后,会将凭据存放在该地址

    NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];

    // 从沙盒中获取到购买凭据

    NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];

    //发送POST请求,对购买凭据进行验证

    //测试验证地址:https://sandbox.itunes.apple.com/verifyReceipt

    //正式验证地址:https://buy.itunes.apple.com/verifyReceipt

    NSURL *url = [NSURL URLWithString:AppStore_URL];

    NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:15.0f];

    urlRequest.HTTPMethod = @"POST";

    NSString *encodeStr = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];

    _receipt = encodeStr;

    NSString *payload = [NSString stringWithFormat:@"{\"receipt-data\" : \"%@\"}", encodeStr];

    NSData *payloadData = [payload dataUsingEncoding:NSUTF8StringEncoding];

    urlRequest.HTTPBody = payloadData;

    NSData *result = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:nil error:nil];

    if (result == nil) {

        NSLog(@"验证失败");

        return;

    }

    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:result options:NSJSONReadingAllowFragments error:nil];

    NSLog(@"请求成功后的数据:%@",dic);

    //这里可以通过判断 state == 0 验证凭据成功,然后进入自己服务器二次验证,,也可以直接进行服务器逻辑的判断。

    //本地服务器验证成功之后别忘了 [[SKPaymentQueue defaultQueue] finishTransaction: transaction];

    NSString *productId = transaction.payment.productIdentifier;

    NSString *applicationUsername = transaction.payment.applicationUsername;

    NSLog(@"applicationUsername++++%@",applicationUsername);

    NSLog(@"payment.productIdentifier++++%@",productId);

    if (dic != nil) {

        userId = applicationUsername;

        //服务器二次验证

        [self vertifyApplePayRequestWith:transaction];

    }

}

- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

注意:

1.内购必须用真机测试

2.测试时必须退出App Store自己的Apple ID,登录沙盒的测试Apple ID

————————————————

版权声明:本文为CSDN博主「Looking.」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qq_22080737/article/details/79786500

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容