什么是内购?
只要在iPhone App上购买的不是实物产品(也就是虚拟产品如qq币.虎牙币.电子书......) 都需要走内购流程,苹果这里面抽走三成。
 
使用内购需要走的流程。
1,填写协议,税务和银行业务;
2,填写用户和职能; 创建内购的项目
3,写代码,和后台配合
4,添加项目内购测试账号;检验成果
 
具体步骤:
接下来的步骤特别繁琐,请做好准备。
一.填写协议,税务和银行业务配置  https://itunesconnect.apple.com/login

1.请求合同

填写地址信息

阅读同意协议

2.填写联系方式

添加新的联系人

选中联系人

3.填写银行信息

添加银行卡

选择银行卡所在国家

 填写银行CNAPS Code

货币类型 CN银行账号如果是对公的账号,需要填写公司的英文名称,如果没有的话拼音
4.填写税务信息
U.S Tax Forms: 美国税务
Australia Tax Forms:澳大利亚税务
Canada Tax Forms: 加拿大税务
第二个问题如下:询问你有没有在美国的商业性活动,没有也直接选No
然后填写你的税务信息,包括以下几点:
Individual or Organization Name:个人或者组织名称
Country of incorporation: 所在国家
Type of Beneficial Owner:受益方式,独立开发者选个人
Permanent Residence:居住地址
Mailing address:邮寄地址
Name of Person Making this Declaration:声明人
Title:头衔
填写完这些信息后就可以提交了
5.等待审核,时间24小时左右。
 
二.创建内购项目
选中你要添加内购项目的APP然后点击功能,点击+创建内购项目。
 根据自己APP的需求选择类型
添加沙盒技术测试员
用户职能>沙箱技术测试员
  
注意事项:
 邮箱随便写但是格式要正确(test@163.com),但是不能用已经是AppleID的邮箱
App Store 地区不要乱选。虽然随便哪个地区都可以用来测试(还没上线之前app并没有地区之分),但是在沙盒测试的时候,弹出的购买提示框会根据当前AppleID(沙盒账号)的地区显示语言的。
使用沙盒测试一定要用真机 (越狱的不行)
沙盒账号不能直接登录AppleStore登录时会提示"不允许创建iTunes账户”
进行沙盒测试时需要退出AppleStore的账号
 
三.代码
 
#import <Foundation/Foundation.h>
#import "WXApi.h"
 
typedef NS_ENUM(NSInteger , Payment) {
    IAP6 = 6,
    IAP25 = 25,
    IAP60 = 60
};
 
@interface PayCenter : NSObject
 
singleton_interface(PayCenter);
 
- (void)startInit;
 
- (void)payWithMoney:(NSInteger)money andType:(PayType)type dataDic:(NSDictionary *)dataDic;
 
@property (nonatomic, strong) MBProgressHUD * hud;
 
@property (nonatomic, copy) NSString * rechargeNumber;
 
@end
 
 
#define kProductID_IAP6 @"org.qqhl.nursning.3175"//6
 
#import "PayCenter.h"
#import "PayHttpRequest.h"
//#import "Order.h"
//#import "DataSigner.h"
//#import <AlipaySDK/AlipaySDK.h>
#import <StoreKit/StoreKit.h>
 
 
@interface PayCenter()<SKPaymentTransactionObserver,SKProductsRequestDelegate>
{
    int buyType;
    NSInteger _money;
}
@property (nonatomic, strong) NSMutableDictionary * dataDic;
 
@end
@implementation PayCenter
 
singleton_implementation(PayCenter);
 
- (void)startInit
{
    [WXApi registerApp:kWeChatShareAppKey withDescription:appDefaultTilte];
}
 
- (void)payWithMoney:(NSInteger)money andType:(PayType)type dataDic:(NSDictionary *)dataDic
{
    _money = money;
    self.dataDic = [NSMutableDictionary dictionaryWithDictionary:dataDic];
    switch (type) {
        case PayTypeWX:
            [self payTypeWXPay];
            break;
        case ApplePay:
//            [self payTypeAliPay];
            [[SKPaymentQueue defaultQueue]addTransactionObserver:self];
           
            if ([SKPaymentQueue canMakePayments]) {
                HULog(@"允许程序内付费购买");
 
                [self payTypeApplePay];
            }else {
                HULog(@"不允许程序内付费购买");
                UIAlertView *alerView =  [[UIAlertView alloc] initWithTitle:@"提示"
                                                                    message:@"您的手机没有打开程序内付费购买"
                                                                   delegate:nil cancelButtonTitle:NSLocalizedString(@"关闭",nil) otherButtonTitles:nil];
               
                [alerView show];
               
            }
 
            break;
        default:
            break;
    }
}
- (NSString *)payTypeWXPay
{
    __block NSString * str = @"";
    [PayHttpRequest payRequestWithType:PayTypeWX dataDic:self.dataDic success:^(BOOL success, NSDictionary *dic) {
        if (success) {
            if (dic != nil) {
                NSDictionary * orderDic = [dic objectForKey:@"orderInfo"];
                NSMutableString *stamp  = [orderDic objectForKey:@"timestamp"];
                //调起微信支付
                PayReq* req             = [[PayReq alloc] init];
                req.partnerId          = [orderDic objectForKey:@"partnerid"];
                req.prepayId            = [orderDic objectForKey:@"prepayid"];
                req.nonceStr            = [orderDic objectForKey:@"noncestr"];
                req.timeStamp          = stamp.intValue;
                req.package            = [orderDic objectForKey:@"package"];
                req.sign                = [orderDic objectForKey:@"sign"];
                [WXApi sendReq:req];
            }else{
                [[PayCenter sharedPayCenter].hud hide:YES];
                str = @"服务器返回错误,未获取到json对象";
            }
        }
    }];
    return str;
}
- (void)payTypeApplePay{
    NSLog(@"---------请求对应的产品信息------------");
    NSArray *product = nil;
    switch (_money) {
        case IAP6:
        {
            product=[[NSArray alloc] initWithObjects:@"org.qqhl.nursning.6",nil];
            NSLog(@"---------IAP6------------");
 
        }
            break;
        case IAP25:
        {
            NSLog(@"---------IAP25------------");
 
        }
            break;
        case IAP60:
        {
            NSLog(@"---------IAP60------------");
        }
 
            break;
    
        default:
            break;
    }
   
    NSSet *nsSet = [NSSet setWithArray:product];
    SKProductsRequest *request = [[SKProductsRequest alloc]initWithProductIdentifiers:nsSet];
    request.delegate = self;
    [request start];
}
#pragma mark -  SKProductsRequestDelegate代理
//返回的在苹果服务器请求的产品信息
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
    HULog(@"收到产品信息");
    NSArray *myProduct = response.products;
    HULog(@"产品id %@",response.invalidProductIdentifiers);
    NSLog(@"产品付费数量%d",(int)[myProduct count]);
//populate UI
    for (SKProduct *product in myProduct) {
      NSLog(@"product info");
      NSLog(@"SKProduct 描述信息%@", [product description]);
      NSLog(@"产品标题 %@" , product.localizedTitle);
      NSLog(@"产品描述信息: %@" , product.localizedDescription);
      NSLog(@"价格: %@" , product.price);
      NSLog(@"Product id: %@" , product.productIdentifier);
    }
    SKPayment *payment = nil;
    switch (_money) {
        case IAP6:
        {
            payment = [SKPayment paymentWithProductIdentifier:kProductID_IAP6];
        }
            break;
        case IAP25:{
           
        }
        default:
            break;
    }
   
    NSLog(@"发起购买请求");
    [[SKPaymentQueue defaultQueue]addPayment:payment];
   
   
}
//实现监听方法
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions{
    NSLog(@"调用了几次这个方法?");
    SKPaymentTransaction *transaction = transactions.lastObject;
    switch (transaction.transactionState) {
        case SKPaymentTransactionStatePurchased: {
            NSLog(@"购买完成,向自己的服务器验证 ---- %@", transaction.payment.applicationUsername);
            NSData *data = [NSData dataWithContentsOfFile:[[[NSBundle mainBundle] appStoreReceiptURL] path]];
            NSString *receipt = [data base64EncodedStringWithOptions:0];
//            [self buySuccessWithReceipt:receipt transaction:transaction];
        }
            break;
        case SKPaymentTransactionStateFailed: {
            NSLog(@"交易失败");
            [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
        }
            break;
        case SKPaymentTransactionStateRestored: {
            NSLog(@"已经购买过该商品");
            [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
        }
            break;
        case SKPaymentTransactionStatePurchasing: {
            NSLog(@"商品添加进列表");
        }
            break;
        default: {
            NSLog(@"这是什么情况啊?");
        }
            break;
    }
}
 
@end

iOS内购图文流程(2017)的更多相关文章

  1. iOS - 内购总结

        如果有人以后要在做内购这一块.希望可以好好的阅读这篇文章,虽然不是字字珠玑.但是也是本人亲人趟过了无数的坑,希望可以对大家有所帮助!  下面是在研究工程中遇到的问题(iOS 内购的流程如下 1 ...

  2. iOS开发内购图文教程

    2015年最全的内购图文教程,首先是填各种资料,最后是代码,废话不多说,直接上图 ======================第一部分协议=============== 第一步.png 第二步.jpg ...

  3. iOS 内购讲解

    一.总说内购的内容 1.协议.税务和银行业务 信息填写 2.内购商品的添加 3.添加沙盒测试账号 4.内购代码的具体实现 5.内购的注意事项 二.协议.税务和银行业务 信息填写 2.1.协议.税务和银 ...

  4. IOS内购支付server验证模式

    IOS 内购支付两种模式: 内置模式 server模式 内置模式的流程: app从app store 获取产品信息 用户选择须要购买的产品 app发送支付请求到app store app store ...

  5. IOS内购支付服务器验证模式

    IOS 内购支付两种模式: 内置模式 服务器模式 内置模式的流程: app从app store 获取产品信息 用户选择需要购买的产品 app发送支付请求到app store app store 处理支 ...

  6. Unity苹果(iOS)内购接入(Unity内置IAP)

    https://www.jianshu.com/p/4045ebf81a1c Unity苹果(iOS)内购接入(Unity内置IAP) Kakarottog                       ...

  7. 苹果IOS内购二次验证返回state为21002的坑

    项目是三四年前的老项目,之前有IOS内购二次验证的接口,貌似很久都没用了,然而最近IOS的妹子说接口用不了,让我看看啥问题.接口流程时很简单的,就是前端IOS在购买成功之后,接收到receipt后进行 ...

  8. iOS 内购相关

    iOS 内购相关 下面总结一下过往订阅和内购的项目的代码方面的实现细节和注意事项,特别是掉单方面的处理. 后台的协议.商品ID.银行卡.内购类型.沙盒账号测试人员都由运营或者产品在苹果后台中申请处理. ...

  9. iOS-IAP内购的那些事(iOS内购漏单的问题)

    前言 说起内购,其实挺令开发者厌烦的,原因呢,先不说漏单的问题,首先苹果要扣除30%的销售额哦,可恨不?(我觉得可恨),有些想办法先隐藏掉第三方支付(支付宝.微信等),等项目上线了,再跳过内购使用第三 ...

随机推荐

  1. hdu1540线段树

    https://vjudge.net/contest/66989#problem/I #include<iostream> #include<cstdio> #include& ...

  2. python中从文件中读取数据

    # average5.py def main(): fileName = input("What file are the numbers in?") infile = open( ...

  3. Java线程安全性中的对象发布和逸出

    发布(Publish)和逸出(Escape)这两个概念倒是第一次听说,不过它在实际当中却十分常见,这和Java并发编程的线程安全性就很大的关系. 什么是发布?简单来说就是提供一个对象的引用给作用域之外 ...

  4. struts2.3.23升级到struts2.3.32

    新的漏洞 3月8号去审计厅培训系统的使用,那边计算机中心的负责人递过来一张如下图所示的文档,意思是发现了struts2的漏洞,需要进行修复. 在培训前,我登录到服务器中,看到了项目中,所有的服务器中应 ...

  5. Python的join()函数和split()函数

    join()方法 ------------------------------------------------------------------------------------------- ...

  6. java集合(1)- 类底层数据结构分析

    Java 集合类图 参考:http://www.cnblogs.com/xwdreamer/archive/2012/05/30/2526822.html

  7. List集合数据太多进行分批,List的subList方法应用

    List<String> mStrings=new ArrayList<>(); //初始化 for (int i = 0; i < 1020; i++) { mStri ...

  8. 发布自己第一个npm 组件包(基于Vue的文字跑马灯组件)

    一.前言 总结下最近工作上在移动端实现的一个跑马灯效果,最终效果如下: 印象中好像HTML标签的'marquee'的直接可以实现这个效果,不过 HTML标准中已经废弃了'marquee'标签 既然HT ...

  9. Linux 库文件详解

    转自: http://www.cppblog.com/deane/articles/165216.html http://blog.sciencenet.cn/blog-1225851-904348. ...

  10. ZooKeeper分布式锁浅谈(一)

    一.概述 清明节的时候写了一篇分布式锁概述,里面介绍了分布式锁实现的几种方式,其实那时候我一直沉迷于使用redis的悲观锁和乐观锁来实现分布式锁,直到一个血案的引发才让我重新认识了redis分布式锁的 ...