ios 虚拟商品 支付用第三方支付 虚拟账户微信支付可以吗

IOS客户端接入微信支付
字体:[ ] 类型:转载 时间:
对于一个ios的app,如果有一些虚拟的商品或者服务需要通过在线支付来收费的话,一般有几种主流的选择。如果是通过APP调用支付平台APP的思路的话,一个是调起支付宝客户端,一个则是调起微信支付。本文给大家分享ios客户端接入微信支付,需要的朋友可以参考下
实际上,从代码的角度,调起支付APP就是把一些关键的参数通过一定方式打包成为一个订单,然后发送到支付平台的服务器。所以,只要搞清楚了参数设置,搞清楚了每个支付平台的SDK里面一些关键API的使用,基本上就可以很简单的支持支付。
今天记录一下客户端里面,如何支持微信支付。首先。我们要仔细阅读一下微信SDK的开发文档,了解一下整个支付的大概流程。
然后根据提示,把相应的SDK下载下来,所谓的SDK,也就是一个链接库和两个头文件,很简单。
下载完毕,需要把SDK导入到工程里面,并且配置一下工程。因为开发者文档已经有详细描述,这里就不再复述。
从文档看到,调起微信支付其实最核心的是一下这么一段
&code class="hljs" vbscript=""&PayReq *request = [[[PayReq alloc] init] autorelease];
request.partnerId = @;
request.prepayId= @fc314aa427;
request.package = @Sign=WXP
request.nonceStr= @a462b76eed6e13c64b4fd1c;
request.timeStamp= @;
request.sign= @DD2B03AD8CB16E7A256;
[WXApi sendReq:request];&/code&
这里的范例是一段hardcode,真正使用的时候,参数都需要自行传入。
为了搞清楚如何使用API,我们可以下载Sample代码。不过,这个sample代码应该是微信的实习生写的,而且应该是一个对于C++比较熟悉,对于ObjectC比较陌生的实习生。。。代码风格可以看出很多东西哈。。所以这个sample读起来总觉得有点奇怪。当然,写出这个demo也是需要不错的水平,因为这个sample不仅仅是一些API的调用,还包括了一些算法的实现,MD5之类的。
看懂了sample之后,一般可以自己重构一下,成为自己APP里面的一个Manager类。
我是在下载的微信Sampel代码,里面包括有:
payRequestHandler.h
payRequestHandler.m
如果比较看重命名规范的OC程序猿,就会觉得这个payRequestHandler类非常别扭,不符合camel命名规则,而且handler这个词更偏向于c++风格。我就以这个类为原型,重构了一下,并改装成一个传参的方法,供自己的APP调用。APP里面卖商品,一般就是商品名字,价格两个关键参数。所以这个重构的方法也只是提供这两个参数的接口。
ApiXml.h && ApiXml.m && WXUtil.h && WXUtil.m不变
&code class="hljs" objectivec=""&//
// WechatPayManager.h
// Created by HuangCharlie on 5/24/15.
#import &foundation foundation.h=""&
#import WXUtil.h
#import ApiXml.h
#import WXApi.h
// 账号帐户资料
// 更改商户把相关参数后可测试
#define APP_ID
@wx@@@@@@@@@@@@@@@@
#define APP_SECRET
//appsecret,看起来好像没用
//商户号,填写商户对应参数
#define MCH_ID
@@@@@@@@@@@
//商户API密钥,填写相应参数
#define PARTNER_ID
//支付结果回调页面
#define NOTIFY_URL
@http://wxpay./pub_v2/pay/notify.v2.php
//获取服务器端支付数据地址(商户自定义)(在小吉这里,签名算法直接放在APP端,故不需要自定义)
#define SP_URL
@http://wxpay./pub_v2/app/app_pay.php
@interface WechatPayManager : NSObject
//预支付网关url地址
@property (nonatomic,strong) NSString* payU
//debug信息
@property (nonatomic,strong) NSMutableString *debugI
@property (nonatomic,assign) NSInteger lastErrC//返回的错误码
//商户关键信息
@property (nonatomic,strong) NSString *appId,*mchId,*spK
//初始化函数
-(id)initWithAppID:(NSString*)appID
mchID:(NSString*)mchID
spKey:(NSString*)
//获取当前的debug信息
-(NSString *) getDebugI
//获取预支付订单信息(核心是一个prepayID)
- (NSMutableDictionary*)getPrepayWithOrderName:(NSString*)name
price:(NSString*)price
device:(NSString*)
&/foundation&&/code&
&code class="hljs" objectivec=""&//
// WechatPayManager.m
// Created by HuangCharlie on 5/24/15.
#import WechatPayManager.h
@implementation WechatPayManager
//初始化函数
-(id)initWithAppID:(NSString*)appID mchID:(NSString*)mchID spKey:(NSString*)key
self = [super init];
//初始化私有参数,主要是一些和商户有关的参数
self.payUrl
= @https://api.mch./pay/
if (self.debugInfo == nil){
self.debugInfo = [NSMutableString string];
[self.debugInfo setString:@];
self.appId = appID;//微信分配给商户的appID
self.mchId = mchID;//
self.spKey =//商户的密钥
//获取debug信息
-(NSString*) getDebugInfo
NSString *res = [NSString stringWithString:self.debugInfo];
[self.debugInfo setString:@];
//创建package签名
-(NSString*) createMd5Sign:(NSMutableDictionary*)dict
NSMutableString *contentString =[NSMutableString string];
NSArray *keys = [dict allKeys];
//按字母顺序排序
NSArray *sortedArray = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [obj1 compare:obj2 options:NSNumericSearch];
//拼接字符串
for (NSString *categoryId in sortedArray) {
![[dict objectForKey:categoryId] isEqualToString:@]
&& ![categoryId isEqualToString:@sign]
&& ![categoryId isEqualToString:@key]
[contentString appendFormat:@%@=%@&, categoryId, [dict objectForKey:categoryId]];
//添加key字段
[contentString appendFormat:@key=%@, self.spKey];
//得到MD5 sign签名
NSString *md5Sign =[WXUtil md5:contentString];
//输出Debug Info
[self.debugInfo appendFormat:@MD5签名字符串:
,contentString];
return md5S
//获取package带参数的签名包
-(NSString *)genPackage:(NSMutableDictionary*)packageParams
NSString *
NSMutableString *reqPars=[NSMutableString string];
//生成签名
= [self createMd5Sign:packageParams];
//生成xml的package
NSArray *keys = [packageParams allKeys];
[reqPars appendString:@&xml&
for (NSString *categoryId in keys) {
[reqPars appendFormat:@&%@&%@&!--%@--&
, categoryId, [packageParams objectForKey:categoryId],categoryId];
[reqPars appendFormat:@&sign&%@&/sign&
&/xml&, sign];
return [NSString stringWithString:reqPars];
//提交预支付
-(NSString *)sendPrepay:(NSMutableDictionary *)prePayParams
NSString *prepayid =
//获取提交支付
NSString *send
= [self genPackage:prePayParams];
//输出Debug Info
[self.debugInfo appendFormat:@API链接:%@
, self.payUrl];
[self.debugInfo appendFormat:@发送的xml:%@
//发送请求post xml数据
NSData *res = [WXUtil httpSend:self.payUrl method:@POST data:send];
//输出Debug Info
[self.debugInfo appendFormat:@服务器返回:
,[[NSString alloc] initWithData:res encoding:NSUTF8StringEncoding]];
XMLHelper *xml = [[XMLHelper alloc] autorelease];
//开始解析
[xml startParse:res];
NSMutableDictionary *resParams = [xml getDict];
//判断返回
NSString *return_code
= [resParams objectForKey:@return_code];
NSString *result_code
= [resParams objectForKey:@result_code];
if ( [return_code isEqualToString:@SUCCESS] )
//生成返回数据的签名
NSString *sign
= [self createMd5Sign:resParams ];
NSString *send_sign =[resParams objectForKey:@sign] ;
//验证签名正确性
if( [sign isEqualToString:send_sign]){
if( [result_code isEqualToString:@SUCCESS]) {
//验证业务处理状态
= [resParams objectForKey:@prepay_id];
return_code = 0;
[self.debugInfo appendFormat:@获取预支付交易标示成功!
self.lastErrCode = 1;
[self.debugInfo appendFormat:@gen_sign=%@
,sign,send_sign];
[self.debugInfo appendFormat:@服务器返回签名验证错误!!!
self.lastErrCode = 2;
[self.debugInfo appendFormat:@接口返回错误!!!
- (NSMutableDictionary*)getPrepayWithOrderName:(NSString*)name
price:(NSString*)price
device:(NSString*)device
//订单标题,展示给用户
NSString* orderName =
//订单金额,单位(分)
NSString* orderPrice =//以分为单位的整数
//支付设备号或门店号
NSString* orderDevice =
//支付类型,固定为APP
NSString* orderType = @APP;
//发器支付的机器ip,暂时没有发现其作用
NSString* orderIP = @196.168.1.1;
//随机数串
srand( (unsigned)time(0) );
NSString *noncestr = [NSString stringWithFormat:@%d, rand()];
NSString *orderNO
= [NSString stringWithFormat:@%ld,time(0)];
//================================
//预付单参数订单设置
//================================
NSMutableDictionary *packageParams = [NSMutableDictionary dictionary];
[packageParams setObject: self.appId forKey:@appid];
//开放平台appid
[packageParams setObject: self.mchId forKey:@mch_id];
[packageParams setObject: orderDevice forKey:@device_info]; //支付设备号或门店号
[packageParams setObject: noncestr
forKey:@nonce_str];
[packageParams setObject: orderType
forKey:@trade_type]; //支付类型,固定为APP
[packageParams setObject: orderName
forKey:@body];
//订单描述,展示给用户
[packageParams setObject: NOTIFY_URL forKey:@notify_url]; //支付结果异步通知
[packageParams setObject: orderNO
forKey:@out_trade_no];//商户订单号
[packageParams setObject: orderIP
forKey:@spbill_create_ip];//发器支付的机器ip
[packageParams setObject: orderPrice
forKey:@total_fee];
//订单金额,单位为分
//获取prepayId(预支付交易会话标识)
NSString *preP
prePayid = [self sendPrepay:packageParams];
if(prePayid == nil)
[self.debugInfo appendFormat:@获取prepayid失败!
//获取到prepayid后进行第二次签名
*package, *time_stamp, *nonce_
//设置支付参数
time(&now);
time_stamp = [NSString stringWithFormat:@%ld, now];
nonce_str = [WXUtil md5:time_stamp];
//重新按提交格式组包,微信客户端暂只支持package=Sign=WXPay格式,须考虑升级后支持携带package具体参数的情况
= [NSString stringWithFormat:@Sign=%@,package];
= @Sign=WXP
//第二次签名参数列表
NSMutableDictionary *signParams = [NSMutableDictionary dictionary];
[signParams setObject: self.appId forKey:@appid];
[signParams setObject: self.mchId forKey:@partnerid];
[signParams setObject: nonce_str
forKey:@noncestr];
[signParams setObject: package
forKey:@package];
[signParams setObject: time_stamp
forKey:@timestamp];
[signParams setObject: prePayid
forKey:@prepayid];
//生成签名
NSString *sign = [self createMd5Sign:signParams];
//添加签名
[signParams setObject: sign
forKey:@sign];
[self.debugInfo appendFormat:@第二步签名成功,sign=%@
//返回参数列表
return signP
@end&/code&
然后,在需要调用微信支付的Controller里面,新建一个方法。在合适的地方调用。这个方法里面利用WechatPayManager这个类进行了初始化和参数封装,然后把上述的核心代码(PayReq那一段)
&code class="hljs" objectivec=""&- (void)wxPayWithOrderName:(NSString*)name price:(NSString*)price
//创建支付签名对象 && 初始化支付签名对象
WechatPayManager* wxpayManager = [[[WechatPayManager alloc]initWithAppID:APP_ID mchID:MCH_ID spKey:PARTNER_ID] autorelease];
//获取到实际调起微信支付的参数后,在app端调起支付
//生成预支付订单,实际上就是把关键参数进行第一次加密。
NSString* device = [[UserManager defaultManager]userId];
NSMutableDictionary *dict = [wxpayManager getPrepayWithOrderName:name
price:price
device:device];
if(dict == nil){
//错误提示
NSString *debug = [wxpayManager getDebugInfo];
NSMutableString *stamp = [dict objectForKey:@timestamp];
//调起微信支付
PayReq* req
= [[[PayReq alloc] init]autorelease];
req.openID
= [dict objectForKey:@appid];
req.partnerId
= [dict objectForKey:@partnerid];
req.prepayId
= [dict objectForKey:@prepayid];
req.nonceStr
= [dict objectForKey:@noncestr];
req.timeStamp
= stamp.intV
req.package
= [dict objectForKey:@package];
= [dict objectForKey:@sign];
BOOL flag = [WXApi sendReq:req];
BOOL flag = [WXApi safeSendReq:req];
再者,支付完成了需要调用一个delegate,这个delegate方便个性化显示支付结果。一般直接把这两个delegate放在AppDelegate就好了。因为有一些其他内容也是需要在AppDelegate里面实现,省的分开找不到。
&code class="hljs" objectivec=""&-(void) onResp:(BaseResp*)resp
//启动微信支付的response
NSString *strMsg = [NSString stringWithFormat:@errcode:%d, resp.errCode];
if([resp isKindOfClass:[PayResp class]]){
//支付返回结果,实际支付结果需要去微信服务器端查询
switch (resp.errCode) {
strMsg = @支付结果:成功!;
strMsg = @支付结果:失败!;
strMsg = @用户已经退出支付!;
strMsg = [NSString stringWithFormat:@支付结果:失败!retcode = %d, retstr = %@, resp.errCode,resp.errStr];
注意事项:
1)如果APP里面已经使用了ShareSDK,就有一些地方要注意。不要再重复导入微信的SDK,因为shareSDK里面的extend已经包括了微信的SDK。
2)微信本身是鼓励客户APP把签名算法放到服务器上面,这样信息就不容易被破解。但是如果客户APP本身没有服务器端,或者认为不需要放到服务器端,也可以直接把签名(加密)的部分直接放在APP端。Sample代码的注释有点乱,多次提到服务器云云,但是其实可以不这么做。
3)微信的price单位是分。注意下即可。
4)暂时想不到,以后想到了再记录。。
以上是本文给大家叙述的IOS客户端接入微信支付的全部内容,希望大家喜欢。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具您的位置: >
苹果官网、Apple Store app支持微信支付啦!(组图) 19:02 来源: 作者:
   iPhone中文网今天iPhone SE、9.7英寸iPad Pro国行版正式开卖,好消息是,除了支付宝,苹果官网现在也能使用微信支付了。不少网友发现在结账时能
  iPhone中文网今天iPhone SE、9.7英寸iPad Pro国行版正式开卖,好消息是,除了宝,现在也能使用了。不少网友发现在结账时能够使用扫码支付了。  据悉,微信支付现已正式登陆.com/cn以及
app。从现在起,
,顾客在网站以及
app上购买包括iPhone、iPad、 Watch等的全线以及相关配件时,可选择使用微信支付进行付款。PC端网站购买界面 Store app购买界面  除此之外,顾客用浏览器打开网站购买产品时也可使用微信支付付款。
热文推荐:
 分享:
【】【】【】
觉得好顶一下
觉得差踩一下
文明上网,理性发言
本周时尚精彩文集推荐
再看几篇关于
的文章看看知尚时尚家族的
时尚美容奢华搭配明星家居
最受关注品牌
热门话题及内容
晒客生活职场汽车IT
最受关注热门词微信支付限额多少,如何调整微信支付额度
文章作者:老胡 发布时间: 16:43:44 来源:
微信限额多少?在我的卡管理界面,点击已绑定的银行卡,我们就可以查看到相关的限额标准(如左下图),其中实物类商品每日每笔的限额为人民币2000元,虚拟类商品每日每笔限额人民币1000元。如何调整微信支付额度?微信是不支持调整支付额度的,这需要通过银行来修改,可以在微信中绑定的“银行卡详情”页面底部看到相应银行的客服电话,用户可以通过银行客服来进行操作。&
文章标签:
值得期待,赞! 打个酱油!踩一脚!
评分:5.5分
办公,效率,助手办公,协作电视,影视应用市场
体育直播,电视剧游戏,视频,翻译官女性,网购旅游,酒店预订银行,理财播放器,影视,短视频相关问题:
最近很多讨论应用内支付(IAP)的问题,但是好像很少有人看了这个 App Store Review Guidelines
()之后再来看这到底是个什么问题。 引起争议的是这几条:11.2Apps utilizing a system other than the In-App Purchase API (IAP) to purchase content, functionality, or services in an App will be rejected11.3Apps using IAP to purchase physical goods or goods and services used outside of the application will be rejected11.4Apps that use IAP to purchase credits or other currencies must consume those credits within the application11.2 说在 App 内使用非 IAP 的第三方支付购买内容或服务、解锁功能是不允许的;11.3 说用 IAP 购买实物或者应用外的货物或服务是不允许的;11.3 说通过 IAP 购买的货币必须只在 App 内使用。我们抠一下字眼就知道问题在哪儿,11.2 告诉你在 iOS App 内部不要使用第三方支付购买 App 内使用的内容,11.3 告诉你不要使用 IAP 购买在 App 外使用的货品,而这两种商品是可能重合的,即在 iOS 内和外都能使用的内容或服务,这两条审核规则却没有明确重合部分适用哪条规则。所以就我的理解,对于跨平台的电子阅读器应用,只要你在 iOS App 内是通过 IAP 而不是第三方支付来购买电子书,也不用 IAP 来购买不能在 iOS App 内使用却可以在 iOS 以外的平台使用的电子书,在 iOS App 内通过 IAP 、在其他平台上通过第三方支付购买电子书然后双向同步,那就是不违反审核规则的。实际上是个解释权的问题,如果不同的苹果员工对不同的 Apps 把这两条解释出不同的意思,审核的结果就可能不一样。我们之前就这个问题专门询问过 Apple 的客服,他的回答是需要使用跨平台支付和同步功能的应用可以向苹果提出申请,如果申请通过了就可以了,虽然我从来没在苹果网站上找到过这个申请的入口在哪儿。
这是一个好问题,我来随便说说自己的经验。&br&当初在盛大负责做移动支付产品的时候,我们也面临过一样的问题。理论上,在App Store体系里,所有应用的生死大权都归苹果掌控,所以上架不带苹果支付的应用而使用第三方支付是有很大风险的(对第三方支付本身应用也一样有被下架的风险)。&br&&br&之前我们认为,苹果想通过AppStore进行封闭管理,所有涉及支付环节都要抽成,后来发现也不尽然如是。否则淘宝、京东等电商企业将直接被逼得走投无路,要知道,30%的支付渠道成本,即便在国外都是不可想象的,更何况费率平均维持在千分之几万分之几的中国。&br&&br&另外,基于国内网银的现状,我们当时为非WIN非IE浏览器的平台感到担忧——ActiveX控件害人不浅,几乎所有网银都要IE支持……蛋疼。当然,后来支付宝快捷支付让人眼前一亮,这是题外话,暂且不提。&br&&br&随着快捷支付的兴起,我们发现:电商网站也可以开始在IOS平台上不通过苹果支付进行正常支付行为了(拍手)。&br&&br&在&a href=&/question/& class=&internal&&&span class=&invisible&&http://www.&/span&&span class=&visible&&/question/2066&/span&&span class=&invisible&&5419&/span&&span class=&ellipsis&&&/span&&/a& 问题中,Arays提到苹果对使用第三方支付的应用是否违规的判断依据应该”是买的东西是不是需要安装在Apple的系统中使用“。我想大概逻辑如是,否则很多电商应用都要下架了。&br&&br&回到正题,像电子阅读器这种应用,正是卡在了这个限制范围内。&br&我给几个思路(合规不合规,有没有实践成功的都有):&br&1.用目前比较流行的策略,其他平台购买的书可以同步到客户账户下,但是不在AppStore上开发支付功能。好处是不会有下架的风险(不要引导客户去其他平台付款,不然一样被干掉),但会流失一部分销售机会。&br&2.由1衍生的策略,建立虚拟货币体系,客户通过PC或者Android购买虚拟货币,在IOS平台上进行消费。类似的策略还有预付卡(点卡)等。好处是用户在IOS体系里内进行消费,消费的是你的虚拟货币,并不涉及人民币结算,苹果干预起来难度很大。坏处是,这玩意打的是擦边球,可能会被苹果干掉;同时你要有足够的内容和应用去支撑你的虚拟货币账户,例如腾讯Q币、盛大点券等,具有这样的能力。&br&3.放弃不越狱的伙计,收费只针对越狱版本的应用。风险和好处一目了然。&br&4.还没试过,请前辈指点。上传苹果应用审核的时候,付费功能模块用webkit做,显示“更多更新,尽请期待”之类的……一旦上线,服务器端改页面,放出收费页面。这样子是彻底违了苹果的规,不知道苹果会不会有事后检查。另外,应用下载量和热度上去后,难不保会被人盯上……所以一直就没敢干这个事情。&br&&br&感谢&a class=&member_mention& data-hash=&b6fb0b7b9c680& href=&///people/b6fb0b7b9c680& data-tip=&p$b$b6fb0b7b9c680&&@黄继新&/a&在评论中给出了唐茶的案例:&br&自己的账户系统和 Apple ID 绑定,比如唐茶,在网页版支付过了,在 App 里就显示已经购买完成了。如果在 App 里通过 IAP 购买了,在网页版也显示购买完成了。 &br&&br&&br&抛砖引玉,大家随便讨论。
这是一个好问题,我来随便说说自己的经验。当初在盛大负责做移动支付产品的时候,我们也面临过一样的问题。理论上,在App Store体系里,所有应用的生死大权都归苹果掌控,所以上架不带苹果支付的应用而使用第三方支付是有很大风险的(对第三方支付本身应用…
App 内创造一种虚拟货币,各平台用各平台可行的支付方式购买虚拟货币,然后该虚拟货币在 App 内通用,可用于支付不同平台 App 内的书籍以及其他内购项目的费用。
App 内创造一种虚拟货币,各平台用各平台可行的支付方式购买虚拟货币,然后该虚拟货币在 App 内通用,可用于支付不同平台 App 内的书籍以及其他内购项目的费用。
已有帐号?
无法登录?
社交帐号登录
云计算 互联网 游戏 工程师

我要回帖

更多关于 大宗商品 第三方支付 的文章

 

随机推荐