iOS内购(IAP,In App Purchases-在APP内部支付),设置及使用

2023-10-27

项目中使用到了中间货币(金币)的形式来进行功能使用,模式是使用RMB换成-金币比如:(1RMB = 10金币),所以会集成第三方的支付平台,使用了微信和支付宝的第三方平台过后,发现审核失败,被苹果拒绝,查了一查原因,才是因为苹果对app内的中间币的购买必须走苹果内购(比如冲点券,比如买钻石....)。所以无奈只有使用苹果内购,由于苹果内购的步骤很多,设置的东西太多,所以将这步骤记录下来。

首先设置协议

1.打开itunes Connect,选择协议,税务和银行业务


image.png


2.点击Request Contracts(申请合同)下面的,request,点了几个确定和下一步后回到主界面。


image.png


Contact info:联系人信息
Bank info:银行信息
Tax info:税务信息


image.png

3.首先设置联系人信息,点击Contact info下面的 Set up(设置),点击Add New Contract(增加先的联系方式)


image.png


4.填写详情
填写完成后点击save(保存)


image.png


5.在下面的所有项目中都选择刚刚填写的信息,选择后点击右下角的done(完成),你可以创建很多联系人,在不同的职务选择不同的联系人。因为我是独立开发,所以我全部填写的我自己。
Senior Management:高管
Financial:财务
Technical:技术支持
Legal:法务
Marketing:市场推广


image.png


6.设置银行信息,点击Back info下面的Set up,弹出页面

点击Add Bank Account(添加银行账号)


image.png


选择china,后点击next。


image.png


填写了CNAPS Code后点击Next


image.png


会弹出你的银行卡开户地的信息,确认一下点击next


image.png


填写银行卡信息,注意:户主名只能写拼音,比如:李三(Li San)。填完后点击Next


image.png


弹出确定信息页面,在下面打钩后点击Save


image.png

点击了save后就可以在弹出的页面中选择刚刚填写的卡了。选择后点击Save


image.png

7.设置税务信息,点击Tax info下面的Set up,此时联系人信息已经变成可以编辑状态,银行信息为浏览状态。


image.png


弹出的界面中,税务分为三种
U.S Tax Forms: 美国税务
Australia Tax Forms:澳大利亚税务
Canada Tax Forms: 加拿大税务
这里我选择的美国税务,就是第一个


image.png


弹出第一个选择,点击submit(提交)后,弹出第二个选择


image.png


弹出第二个选择,选择后点击submit


image.png


弹出第三个页面,填写的资料后点击提交,记得勾选页面上的几个复选框


image.png


在提交成功后,状态就变成processing成功


image.png

到这里设置的协议就已经设置完了。

创建项目的内购

1.进入到项目的APP信息页面,点击功能,在弹出的页面点击App内购买项目后面的➕。


image.png

2.在弹出的新对话框中选择你需要哪一种服务,由于我的项目需要兑换成消耗的金币,所以我选择第一个。选择后点击创建。


image.png


3.开始填写内购项目信息。填完后点击右上角的存储(所有信息必须填写完整)。


image.png

4.点击存储后,内购列表就会有刚刚创建的内购条目。


image.png


你app有几个内购级别就需要依次创建几个条目。

添加测试账号,用来测试支付功能

1.点击图中用户和职能


image.png


2.点击沙盒测试员,然后点击左边的➕按钮。


image.png


3.设置好信息点击右上角存储就可以,记住里面的邮箱和密码用于支付的时候登陆Apple id


image.png

代码集成

打开自己的项目,创建一个测试类。代码都有注释和步骤,直接上代码。

注意:

1.必须用真机测试。
2.测试的时候必须退出自己的apple ID。弹出页面后登陆沙盒的测试apple id。

#import "TestPayController.h"

// 1.首先导入支付包
#import <StoreKit/StoreKit.h>

// 2.设置代理服务
@interface TestPayController ()<SKPaymentTransactionObserver,SKProductsRequestDelegate>

@end

@implementation TestPayController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];

    //3.创建测试按钮
    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.设置支付服务
    [[SKPaymentQueue defaultQueue] addTransactionObserver:self];


}

//点击测试按钮
- (void)clickTestBtnAction
{

    // 5.点击按钮的时候判断app是否允许apple支付

    //如果app允许applepay
    if ([SKPaymentQueue canMakePayments]) {
        NSLog(@"yes");

        // 6.请求苹果后台商品
        [self getRequestAppleProduct];
    }
    else
    {
        NSLog(@"not");
    }
}

//请求苹果商品
- (void)getRequestAppleProduct
{
    // 7.这里的com.czchat.CZChat01就对应着苹果后台的商品ID,他们是通过这个ID进行联系的。
    NSArray *product = [[NSArray alloc] initWithObjects:@"com.czchat.CZChat01",nil];

    NSSet *nsset = [NSSet setWithArray:product];

    // 8.初始化请求
    SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:nsset];
    request.delegate = self;

    // 9.开始请求
    [request start];
}

// 10.接收到产品的返回信息,然后用返回的商品信息进行发起购买请求
- (void) productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response
{
    NSArray *product = response.products;

    //如果服务器没有产品
    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.如果后台消费条目的ID与我这里需要请求的一样(用于确保订单的正确性)
        if([pro.productIdentifier isEqualToString:@"com.czchat.CZChat01"]){
            requestProduct = pro;
        }
    }

    // 12.发送购买请求
    SKPayment *payment = [SKPayment paymentWithProduct:requestProduct];
    [[SKPaymentQueue defaultQueue] addPayment:payment];
}

//请求失败
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error{
    NSLog(@"error:%@", error);
}

//反馈请求的产品信息结束后
- (void)requestDidFinish:(SKRequest *)request{
    NSLog(@"信息反馈结束");
}

// 13.监听购买结果
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transaction{
    for(SKPaymentTransaction *tran in transaction){

        switch (tran.transactionState) {
            case SKPaymentTransactionStatePurchased:
                NSLog(@"交易完成");

                break;
            case SKPaymentTransactionStatePurchasing:
                NSLog(@"商品添加进列表");

                break;
            case SKPaymentTransactionStateRestored:
                NSLog(@"已经购买过商品");

                break;
            case SKPaymentTransactionStateFailed:
                NSLog(@"交易失败");

                break;
            default:
                break;
        }
    }
}

// 14.交易结束,当交易结束后还要去appstore上验证支付信息是否都正确,只有所有都正确后,我们就可以给用户方法我们的虚拟物品了。
- (void)completeTransaction:(SKPaymentTransaction *)transaction
{
    NSString * str=[[NSString alloc]initWithData:transaction.transactionReceipt encoding:NSUTF8StringEncoding];

    NSString *environment=[self environmentForReceipt:str];
    NSLog(@"----- 完成交易调用的方法completeTransaction 1--------%@",environment);


    // 验证凭据,获取到苹果返回的交易凭据
    // appStoreReceiptURL iOS7.0增加的,购买交易完成后,会将凭据存放在该地址
    NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
    // 从沙盒中获取到购买凭据
    NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
    /**
     20      BASE64 常用的编码方案,通常用于数据传输,以及加密算法的基础算法,传输过程中能够保证数据传输的稳定性
     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"];
    }
    //这个二进制数据由服务器进行验证;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];

    //开始请求
    NSError *error=nil;
    NSData *responseData=[NSURLConnection sendSynchronousRequest:connectionRequest returningResponse:nil error:&error];
    if (error) {
        NSLog(@"验证购买过程中发生错误,错误信息:%@",error.localizedDescription);
        return;
    }
    NSDictionary *dic=[NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingAllowFragments error:nil];
    NSLog(@"请求成功后的数据:%@",dic);
//这里可以等待上面请求的数据完成后并且state = 0 验证凭据成功来判断后进入自己服务器逻辑的判断,也可以直接进行服务器逻辑的判断,验证凭据也就是一个安全的问题。楼主这里没有用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);
//这里可以做操作吧用户对应的虚拟物品通过自己服务器进行下发操作,或者在这里通过判断得到用户将会得到多少虚拟物品,在后面([self getApplePayDataToServerRequsetWith:transaction];的地方)上传上面自己的服务器。
        }
    }
//此方法为将这一次操作上传给我本地服务器,记得在上传成功过后一定要记得销毁本次操作。调用[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
    [self getApplePayDataToServerRequsetWith:transaction];
}

//结束后一定要销毁
- (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:@";"];

    //存储收据环境的变量
    NSString * environment=arr[2];
    return environment;
}

@end
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iOS内购(IAP,In App Purchases-在APP内部支付),设置及使用 的相关文章

  • MDK 编译错误:multiply defined (重复定义)

    这个代码实现很简单 出现重复定义首先检查了自己的头文件 发现没问题 后来经过师兄的点拨 发现他提示后面有 表示有两个头文件key1 c和key c 马上检查了工程 果然发现有两个 c文件 删除一个即可解决问题
  • 广度优先探索例题java_LeetCode:广度优先搜索(BFS)算法(常见面试题)

    今天推荐一道常见的面试算法题 比较实用也比较常见 一 认识广度优先搜索算法 广度优先搜索 BFS 算法是图的一种遍历方法 它的核心思想是从图的某一个节点开始 依次遍历相邻节点 再从这些相邻节点继续向外层节点遍历 直到连通图的所有节点均被访问
  • Django-项目构建(一)

    环境 python3 Django2 window10 工具 pycharm 构建项目前期准备工作 安装python3 Django2 等 略 一 使用git Bash Here 打开git bash Here 构建项目命令 django
  • java取html中的table_从一段html的table标签中按列提取信息

    我们平时经常会遇到提取某个html中某个table的信息 比如 我们要提取出序号 登记编号 出质人等等 我的思路是先通过正则锁定该table 在通过Jsoup来按列解析内容 我将提取信息的过程抽取出了一个方法 其中内含Jsoup和Regex
  • idea配置使用git以及ssh key的介绍使用

    文章目录 1 Git GUI 的使用 2 ssh key 的介绍和使用 安装ssh key 3 idea中配置并使用git idea配置git 1 Git GUI 的使用 首先先将 git gui 汉化一下 把msgs文件夹copy到 Gi
  • 本地把虚拟光驱传到服务器,将文件传到服务器

    将文件传到服务器 内容精选 换一换 监控数据上报功能可以将系统中采集到的监控数据写入到文本文件 并以FTP或SFTP的形式上传到指定的服务器中 使用该功能前 管理员需要在FusionInsight Manager页面进行相关配置 监控数据上
  • windows服务程序中创建用户进程

    最近碰到个问题 需要在服务中检测用户桌面的情况 但是服务程序都是SYSTEM账户下运行 属于Session0 不能检测到用户桌面的情况 所以就需要另启一个用户进程来获取这些信息 然后发送给服务 所以就用到了 CreateProcessAsU
  • 卷积神经网络系列之卷积/池化后特征图大小怎么计算??

    1 卷积后的大小 W 矩阵宽 H 矩阵高 F 卷积核宽和高 P padding 需要填充的0的个数 N 卷积核的个数 S 步长 width 卷积后输出矩阵的宽 height 卷积后输出矩阵的高 width W F 2P S 1 向下取整 h
  • 小米路由器mini 安装openWrt+更新源+挂载U盘+安装python

    刚刚入手一个小米路由器mini 本来就是打算装openWrt的 想试试玩玩看 刷openwrt的基本流程是参考的如下博主的文章 http www right com cn forum thread 147929 1 1 html 没有遇到什
  • BUUCTF [极客大挑战 2019]FinalSQL

    极客大挑战 2019 FinalSQL 操作 脚本 总结 操作 打开题目 又是这个鬼 跟着他的流程走 点按钮 让我们试试别的 告诉我们对了 但是不是这张表 埋坑 怀疑这个地址是存在sql注入的 经过fuzz 发现过滤了空格 union之类的
  • DOM方式实现Excel导入

    DOM解析Excel 在我们的工作场景中经常会遇到数据录入的需求 有些批量数据录入太麻烦 就需要用到批量导入的方式来提高效率 这就涉及到读取Excel数据的技术 Appache Poi提供了DOM解析和SAX解析两种方式 本篇主要记录自己工
  • Windows Terminal 安装gsudo插件

    Gsudo Windows下类似于linux的sudo 可用于提权 新建 Windows Terminal 标签页时可以用于新建有管理员的页面 或者直接sudo将当前页面提权 需要在安装过程中把sudo命令和gsudo命令建立关联 Powe
  • elasticsearch python连接池吗_了解Elasticsearch及其与Python的对接实现

    什么是 Elasticsearch 但我们想查数据的时候就免不了搜索 搜索就离不开搜索引擎 百度 谷歌都是一个非常庞大复杂的搜索引擎 他们几乎索引了互联网上开放的所有网页和数据 然而对于我们自己的业务数据来说 肯定就没必要用这么复杂的技术了
  • 使用的工具

    文档 devdocs 开发知识 css tricks css技巧分享 开发工具 可以检测前端代码规范的工具 sonarlint 还未用过 样式工具 collect ui 用来查看设计的ui界面参考 其他工具 虚拟号码生成 https sms
  • CentOS8配置yum/dnf镜像源

    Centos8 dnf命令 DNF意思是 Dandified Yum 这是下一代的yum软件包管理器 Yum的派生 Centos8开始使用dnf工具来管理软件包 它可以在基于RPM的Linux发行版上安装 更新和删除软件包 它会自动计算依赖
  • MATLAB克劳特算法,克劳特(Crout)(LU)分解法求解线性方程组的matlab实现

    克劳特 Crout LU 分解法求解线性方程组的matlab实现 由会员分享 可在线阅读 更多相关 克劳特 Crout LU 分解法求解线性方程组的matlab实现 3页珍藏版 请在人人文库网上搜索 1 1 克劳特 Crout LU 分解法
  • c语言课程主要目的和内容,C语言程序设计课程教学大纲

    C语言程序设计课程教学大纲 C语言程序设计课程教学大纲 一 本课程的性质 目的和任务 1 课程的性质 本课程是计算机科学与技术专业的一门重要的专业基础课程 它既可以为其它专业课程奠定程序设计的基础 又可以作为其它专业课程的程序设计工具 2
  • OpenWRT 增加内核模块及应用方法

    进入package目录 创建模块目录 cd mcp branches V1 1 beta1 mcp package mkdir example 进入example目录 创建Makefile文件和代码路径 cd example touch M
  • VMware虚拟机Linux系统根目录空间扩充操作

    VMWare虚拟机安装的应用多了 导致根目录空间不足 有没有办法可以将根目录空间进行扩充呢 经过搜集各各资料 顺利解决问题 把服务器的空间由6G扩成8G 现将执行全过程总结如下 以 供分享 首先 介绍下大体的解决思路 要想扩充 必须要有一块
  • 最完整的分布式架构设计图谱

    我们身处于一个充斥着分布式系统解决方案的计算机时代 无论是支付宝 微信这样顶级流量产品 还是区块链 IOT 等热门概念 抑或如火如荼的容器生态技术如 Kubernetes 其背后的技术架构核心都离不开分布式系统 为什么要懂分布式架构设计 系

随机推荐

  • CF::B. Odd Swap Sort

    题目大意 有多组测试数据 每组测试数据为一个长度为n的正整数数组 问是否可以通过任意此特定操作 每次操作可以选择挨着的一个为奇数 一个为偶数的两个数交换 使数组变为不严格的升序数组 如果可以的话输出 YES 否则输出 NO time lim
  • git 代码管理工具3

    团队协作分支开发模式 一个好的 github 项目一般都有多个分支 master dev release分支 新建分支 branch git branch branch1 切换到目标分支 git checkout branch1 在本地的b
  • 如何通过轨迹信息判断驾驶人是否为同一人?

    轨迹识别问题旨在验证传入的轨迹是否是由所要求的人员产生 即给定一组单独的人员历史轨迹 例如行人 出租车司机 以及由特定人员生成的一组新轨迹 判定两组轨迹是否由同一个人员生成 这个问题在许多实际应用中都很重要 例如出租车驾驶人员身份认证 汽车
  • 用于独立系统应用的光伏MPPT铅酸电池充电控制器建模(Simulink实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Simulink实现 详细文章 1 概述 本文介绍了MATLAB Simu
  • android开发浅谈之写在前面的话

    自我介绍 先简单的介绍一下我的主要工作经历吧 时间 东家 主要工作 2011年8月 深圳大学毕业 那是安卓开始崛起的前夜 自己整上午整下午的看网上的新品手机 基本上注定了自己从事手机相关的职业选择了 2011年8月 2013年8月 深圳康佳
  • 使用canvas画迁徙线并加上动态效果与小飞机图标

    首先在页面中放上地图图片 并建立三个canvas标签 分别用于点 迁徙线 动态效果 div class mapBox div class map img src assets shanxi svg alt div div
  • 【每日一题见微知著】记录一次力扣周赛全AC

    2185 统计包含给定前缀的字符串 给你一个字符串数组 words 和一个字符串 pref 返回 words 中以 pref 作为 前缀 的字符串的数目 字符串 s 的 前缀 就是 s 的任一前导连续字符串 class Solution p
  • HashMap集合 嵌套ArrayList集合

    开发工具与关键技术 IDEA 撰写时间 2022 5 17 HashMap集合 嵌套ArrayList集合 首先创建一个HashMap集合 HashMap的键值对分别为String和ArrayList字符串的集合 然后在创建一个Arrayl
  • org.apache.tomcat.util.descriptor.web.WebXml.setVersion Unknown version string [4.0]. Default versio

    org apache tomcat util descriptor web WebXml setVersion Unknown version string 4 0 Default version will be used
  • python nltk下载_Python-如何下载NLTK数据?

    小编典典 要下载特定的数据集 模型 请使用nltk download 函数 例如 如果你要下载punkt句子标记器 请使用 python3 gt gt gt import nltk gt gt gt nltk download punkt
  • cocos2dx opengl入门系列一-序言

    入门序言 在开始这个系列之前有必要说明一下这个系列的结构 系列会从最简单的opengl画三角形 gt 再画四边形 gt 显示一个纹理 gt 显示多重纹理 完 就是这样简单直接 好吧 这么简单的原因是本人水平有限 还有一个原因是cocos2d
  • 屏的接口类型种类以及接口定义分析

    一 屏的接口类型大致有 1 SPI SPI 采用较少 连线为CS SLK SDI SDO四根线 连线少但是软件控制比较复杂 一般用于低速黑白小尺寸屏 2 I2C I2C一般用于低速黑白小尺寸屏 3 CPU 在功能机上用的多 4 RGB 大屏
  • Markdown高级

    Markdown高级 警告 Markdown 未正式支持的解决方法 概述 大多数使用 Markdown 的人会发现基本和扩展的语法元素可以满足他们的需求 但很有可能 如果你使用 Markdown 的时间足够长 你会不可避免地发现它不支持你需
  • 微信小程序报错 Error: errCode: -1

    如果你是因为请求云数据库内的数据 那就是权限问题 解决方法如下 勾选 所有用户可读 仅创建者可读写 如果你需要让所有用户都可读写那要怎么办呢 答案是创建云函数 调用云函数写入数据库 因为云函数就是创建者权限
  • RISC-V IDE MRS使用笔记(三):提升浮点计算效率

    RISC V IDE MRS使用笔记 三 提升浮点计算效率 MRS内置CH32V30X系列芯片 此系列芯片支持FPU 浮点计算单元 想要打开时需要开启相应的扩展 如下图所示 此时如果编译单精度类型的浮点变量 就会启用FPU进行浮点计算 提高
  • windows 64位 安装mvn提示 不是内部或外部命令

    在安装mvn的过程中当在mvn的目录下去执行mvn命令的时候是可以正常执行的 当设置好环境变量后执行后发现提示mvn不是内部命令 原因是设置的MAVEN HOME变量未被Path解析 解决办法是 直接把path中的 MAVEN HOME b
  • vue子组件弹窗 el-dialog

    弹窗 在vue中结合elementui 在父组件中通过点击事件 控制子组件弹窗显示 将父组件的值通过props的方式传递给子组件弹窗 子组件通过computed的方式来获取值和设置新值 在set中调用 emit update porp 方法
  • 51nod 1165 整边直角三角形的数量(两种解法)

    链接 http www 51nod com Challenge Problem html problemId 1165 直角三角形 三条边的长度都是整数 给出周长N 求符合条件的三角形数量 例如 N 120 共有3种不同的满足条件的直角3角
  • Understanding and Detecting Software Upgrade Failures in Distributed Systems

    分布式系统中的升级故障 Tips 摘要 介绍 方法论 升级故障的严重程度 升级故障的根本原因 升级故障的触发因素 测试和检测升级故障 未来研究方向 相关工作和总结 后记 Tips 作者主页 论文下载地址 摘要 升级是破坏分布式系统可用性的不
  • iOS内购(IAP,In App Purchases-在APP内部支付),设置及使用

    项目中使用到了中间货币 金币 的形式来进行功能使用 模式是使用RMB换成 金币比如 1RMB 10金币 所以会集成第三方的支付平台 使用了微信和支付宝的第三方平台过后 发现审核失败 被苹果拒绝 查了一查原因 才是因为苹果对app内的中间币的