支付那些小事

现在不管是电商还是一些社区类的App都接入了支付的功能,有的是走的苹果的支付【内购不是Apple Pay】,有的则是支付宝、微信和银联卡,不管是买卖商品还是打赏点赞,这些都是涉及到资金的流动。当然目前据《华尔街日报》,微信和其他公司的高管表示,苹果已经要求几家国内社交网络应用禁用它们的“打赏”功能,以遵守AppStore的规则。即使是这样还可以在打打赏的位置放置一些收款二维码来替代。当然如果真的放二维码了那就跟自己的应用没关系了,所以这一块也不用担心了。那么先说一下应用的内购吧,应用的内购流程(内购的流程具体可参见:http://www.cnblogs.com/liuluoxing/p/6553109.html)其实并不复杂,主要是一些点需要注意:设置卡号选择币种的时候人民币的标识是CNY,接着设置Tax的时候一般在天朝的话直接选择

图1.0

这些是税务信息一般来说U.S Tax Forms: 美国税务、Australia Tax Forms:澳大利亚税务、Canada Tax Forms: 加拿大税务 选择美国税务就可以。签完协议和税务信息,还要记得填写用户的职能即设置沙盒里面的测试账号,这样使用这个账号才能进行测试内购。这些是为内购做的准备,当进行集成的时候推荐一个轮子(RMStore这个开源库),过程中遇到一些问题就是付款过程中的未知错误处理是最多的无法连接到iTunes store,不过查阅一些资料的话可以发现,其实每种状态都有对应的枚举值如下:

enum {
    SKErrorUnknown,
    SKErrorClientInvalid,               // client is not allowed to issue the request, etc.
    SKErrorPaymentCancelled,            // user cancelled the request, etc.
    SKErrorPaymentInvalid,              // purchase identifier was invalid, etc.
    SKErrorPaymentNotAllowed,           // this device is not allowed to make the payment
    SKErrorStoreProductNotAvailable,    // Product is not available in the current storefront
};  

可以根据这几个状态作相应的细节处理,提示用户即可。

接着是支付宝和微信了,先说支付宝吧,在客户端的处理上支付宝的处理相对于微信来说更多一下,被吐槽的地方也更多一些,首先是支付宝的官方集成文档特别特别的难找,要找很久才能找对地方。这个是直达连接

https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.0JY36K&treeId=193&articleId=105295&docType=1

图2.0

涉及到的相关流程即:首先应用端选择支付宝付款,这里分为两种情况,一种是使用公司自己的服务器生成签名,订单号和订单的相关参数值,第二种是应用在客户端自己生成签名和订单信息.因为订单信息中包含签名和秘钥,会造成信息传递的不安全,所以还是建议将生成订单的步骤放在自己的服务器端(最好是服务器给返回的数据是已经拼接好的参数串例如:

{
  "code": 0,
  "message": "SUCCESS",
  "data": [
    {
      "data": "partner=2088121050949991&[email protected]&subject=充值测试&notify_url=http://1xx.xx.xx.xx:8081/v2/notify&payment_type=1&_input_charset=utf-8&it_b_pay=30m&sign=xxxxxxxxxxxx&sign_type=RSA"
    }
  ]
}

)这样客户端就可以直接拿着相应的data里面的返回订单信息去调起支付宝的api,设置好appScheme,直接用调用支付宝的支付接口即可:

  [self sendValueToAliPayWithOrderString:signedString FromScheme:appScheme];

相关的代码为:

- (void)sendValueToAliPayWithOrderString:(NSString *)orderString FromScheme:(NSString *)appScheme
{

    //    提供给商户快捷订单支付功能。  支付并返回回调结果
    [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {

        if ([[resultDic objectForKey:@"resultStatus"]isEqualToString:@"9000"]) {
           // 支付成功的处理,跳转相关界面
        }else  if ([[resultDic objectForKey:@"resultStatus"]isEqualToString:@"4001"]) {
            UIAlertView *av = [[UIAlertView alloc] initWithTitle:nil message:@"请您重新选择支付金额" delegate:self cancelButtonTitle:nil otherButtonTitles:@"确定", nil];
            [av show];

        } else  if ([[resultDic objectForKey:@"resultStatus"]isEqualToString:@"4006"]) {

            UIAlertView *av = [[UIAlertView alloc] initWithTitle:nil message:@"订单支付失败" delegate:self cancelButtonTitle:nil otherButtonTitles:@"确定", nil];
            [av show];

            // 支付失败跳转的界面

        } else if ([[resultDic objectForKey:@"resultStatus"]isEqualToString:@"4003"]) {

            UIAlertView *av = [[UIAlertView alloc] initWithTitle:nil message:@"您的账户目前不能正常支付" delegate:self cancelButtonTitle:nil otherButtonTitles:@"确定", nil];
            [av show];
            // 支付失败跳转的界面

        } else if ([[resultDic objectForKey:@"resultStatus"]isEqualToString:@"6001"]) {

            UIAlertView *av = [[UIAlertView alloc] initWithTitle:nil message:@"您已取消充值" delegate:self cancelButtonTitle:nil otherButtonTitles:@"确定", nil];
            [av show];

        }else {

            UIAlertView *av = [[UIAlertView alloc] initWithTitle:nil message:@"未支付成功" delegate:self cancelButtonTitle:nil otherButtonTitles:@"确定", nil];
            [av show];
            // 支付失败的跳转

        }
    }];
}

除此之外还要在AppDelegate里面做相应的设置,这一块如果做了微信的支付回调的方法也是一致的,等下面说微信支付的时候一块贴上代码。如果签名什么的都在后台服务器做的话,那么在应用中的代码也就这么多。还有几个需要注意的点,就是为了支付成功回调做的准备:

应用注册的时候schme 在Info.plist定义URL types URL schme
将商品信息拼接成字符串
进行签名并将签名成功后的字符串格式化订单字符串
调用支付宝SDK发送数据// 还包括相关错误码

9000 订单支付成功

8000 正在处理中

4000 订单支付失败

6001 用户中途取消

6002 网络连接出错

 

可以画个图展示一下:

图3.0

以上就是支付宝支付所需要注意的点了。下面来说说微信,就像之前说到的,微信支付要比起支付宝支付来讲客户端处理的内容相对的较少一些,其主要的处理都是在服务端,首先可以看一下这个流程,一看就是比较复杂,不过这些都不用客户端来处理

图4.0

简化一下呢,就是是4个步骤,一个就是请求生成的订单数据,另一个就是调起微信支付德的api处理支付的结果;接着就是处理支付的回调结果,最后异步处理,通知服务器支付成功。画个图展示一下具体的步骤吧

图5.0

这些事理论上的表述,涉及到应用中的代码处理可以分为,先从服务器请求相应的数据,服务器返回的数据格式应该为:

{
  "code": 0,
  "message": "SUCCESS",
  "data": [
    {
      "app_id": "wx6a33db7xxxxx",
      "nonce_str": "IVY8yB5q7v6jpSgiVgxxxxxxxx",
      "extend_field": "Sign=WXPay",
      "partner_id": "1333317801",
      "prepay_id": "wx2017022414465218c0066b3d04xxxxxx",
      "timestamp": "1487918812",
      "sign": "D5001641D1F43C5DBA6F14xxxxxxxx"
    }
  ]
}

在后台服务器请求完必要的参数后,此时就应该调起微信支付:具体代码如下:

  if([WXApi isWXAppInstalled]) // 判断 用户是否安装微信
    {
        PayReq *request = [[PayReq alloc] init] ;
        request.partnerId = _myModel.partner_id;
        request.prepayId= _myModel.prepay_id;
        request.package = _myModel.extend_field;
        request.nonceStr= _myModel.nonce_str;
        request.timeStamp= _myModel.timestamp;
        request.sign= _myModel.sign;

        [WXApi sendReq:request];
    }else {

        UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"提示" message:@"未安装微信客户端,请选择其他支付方式" delegate:self cancelButtonTitle:nil otherButtonTitles:@"确定", nil];
        [av show];
   }

再在其回调的方法内设置相应的跳转即可如下:

-(void)dealWXpayResult:(NSNotification*)notification{
    NSString*result=notification.object;
    if([result isEqualToString:@"1"]){
        // 支付成功的操作

    }else{

        //支付失败的操作
        UIAlertView *av = [[UIAlertView alloc] initWithTitle:nil message:@"您已取消支付" delegate:self cancelButtonTitle:nil otherButtonTitles:@"确定", nil];
        [av show];
    }
}

以上是在当前界面下的处理的回调逻辑,除此之外还要在AppDelegate里面设置相关的代理方法具体的设置内容如下所示:

首先是支付宝的:

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{
    if ([url.host isEqualToString:@"safepay"]) {
        // 设备已安装支付宝客户端情况下,处理支付宝客户端返回的 url
        [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
            // 用SBJSON 或者 JSONKit 将回调信息(字典)转成字符串
            SBJSON *sbJson = [[SBJSON alloc] init];
            NSString *resultDicToString = [sbJson stringWithObject:resultDic error:nil];
            [self paymentResult:resultDicToString];
        }];
    }
    if ([url.host isEqualToString:@"platformapi"]){//支付宝钱包快登授权返回 authCode
        [[AlipaySDK defaultService] processAuthResult:url standbyCallback:^(NSDictionary *resultDic) {

        }];
    }
    return YES;
}
// 支付宝回调的新方法
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{
    if ([url.host isEqualToString:@"safepay"]) {
        //   设备已安装支付宝客户端情况下,处理支付宝客户端返回的 url
        [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
            //    用SBJSON 或者 JSONKit 将回调信息(字典)转成字符串
            SBJSON *sbJson = [[SBJSON alloc] init];
            NSString *resultDicToString = [sbJson stringWithObject:resultDic error:nil];
            [self paymentResult:resultDicToString];
            if ([[resultDic objectForKey:@"resultStatus"]isEqualToString:@"9000"]) {
                //    NSLog(@"当前页面下的支付成功");
                [[NSNotificationCenter defaultCenter]postNotificationName:@"chongzhiFinishAction" object:nil];

            }else {

                //    NSLog(@"当前页面下的未支付");
                UIAlertView *av = [[UIAlertView alloc] initWithTitle:nil message:@"您已取消支付" delegate:self cancelButtonTitle:nil otherButtonTitles:@"确定", nil];
                [av show];

            }
        }];
    }else{

        return  [WXApi handleOpenURL:url delegate:self];
    }
    if ([url.host isEqualToString:@"platformapi"]){//支付宝钱包快登授权返回 authCode
        [[AlipaySDK defaultService] processAuthResult:url standbyCallback:^(NSDictionary *resultDic) {

            if ([[resultDic objectForKey:@"resultStatus"]isEqualToString:@"9000"]) {
                //                NSLog(@"当前页面下的支付成功");
                UIAlertView *av = [[UIAlertView alloc] initWithTitle:nil message:@"您已支付成功" delegate:self cancelButtonTitle:nil otherButtonTitles:@"确定", nil];
                [av show];
            }else {
                //                NSLog(@"当前页面下的未支付");
                UIAlertView *av = [[UIAlertView alloc] initWithTitle:nil message:@"您已取消支付" delegate:self cancelButtonTitle:nil otherButtonTitles:@"确定", nil];
                [av show];

            }

        }];
    }else
    {
        return  [WXApi handleOpenURL:url delegate:self];
    }

    return  YES;

}

- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation {
    if ([url.host isEqualToString:@"safepay"]) {
        //    设备已安装支付宝客户端情况下,处理支付宝客户端返回的 url
        [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
            // 用SBJSON 或者 JSONKit 将回调信息(字典)转成字符串
            SBJSON *sbJson = [[SBJSON alloc] init];
            NSString *resultDicToString = [sbJson stringWithObject:resultDic error:nil];
            [self paymentResult:resultDicToString];
        }];
    }else{
        return  [WXApi handleOpenURL:url delegate:self];
    }
    if ([url.host isEqualToString:@"platformapi"]){//支付宝钱包快登授权返回 authCode
        [[AlipaySDK defaultService] processAuthResult:url standbyCallback:^(NSDictionary *resultDic) {

        }];
    }else{
        //          return  [WXApi handleOpenURL:url delegate:self];
    }
    return YES;
}
//#pragma mark - 对独立客户端回调结果验证
- (void)paymentResult:(NSString *)resultDicToString
{
    //结果处理
    AlixPayResult *result = [[AlixPayResult alloc] initWithString:resultDicToString];
    if (result)
    {
        if (result.statusCode == 9000)
        {
            // 验证签名成功,交易结果无篡改
            // NSLog(@"支付成功!");

        }

        else
        {
            // 支付失败
            // NSLog(@"%d%@", result.statusCode, result.statusMessage);
        }
    }
    else
    {
        // 支付失败
        // NSLog(@"支付失败!");
    }

}

接着是微信的:

#pragma mark - 微信支付回调
-(void) onResp:(BaseResp*)resp
{
    NSString *strMsg = [NSString stringWithFormat:@"errcode:%d", resp.errCode];
    NSString *strTitle;

    if([resp isKindOfClass:[SendMessageToWXResp class]])
    {
        strTitle = [NSString stringWithFormat:@"发送媒体消息结果"];
    }
    if([resp isKindOfClass:[PayResp class]]){
        //支付返回结果,实际支付结果需要去微信服务器端查询
        strTitle = [NSString stringWithFormat:@"支付结果"];

        switch (resp.errCode) {
            case WXSuccess:
                strMsg = @"恭喜您支付:成功!";

                [[NSNotificationCenter defaultCenter] postNotificationName:@"WXpayresult" object:@"1"];
                break;

            default:
                strMsg = [NSString stringWithFormat:@"您已取消支付"];

                [[NSNotificationCenter defaultCenter] postNotificationName:@"WXpayresult" object:@"2"];

                break;
        }
    }

}

其实可以看出这两种方式的支付都有重合的地方,需要注意添加判断一下。

对了,最后再说一点吧,如果你app同时使用了友盟分享(含微信分享)和微信支付 要注意两者的register步骤。要先调用友盟,然后调用微信。避免不必要的错误。

时间: 2024-12-14 01:22:50

支付那些小事的相关文章

带有支付功能的产品如何进行测试

软件测试人员在进行测试的时候,根据测试项目或者测试对象的不同,会采用不同的方式方法来进行测试,那么,带有支付功能的产品该如何测试呢?在测试过程中又应该注意些什么?        财务人员有句老话叫:财务无小事.因为,首先,任何涉及到财务的问题,不论金额有多么的小,它在性质上也是严重事件:其次,在各种金融支付功能已深入老百姓生活的方方面面的今天,一个程序中,哪怕仅有一个小小的支付问题,那么,最后引起的也可能是涉及成百上千乃至上亿元金额和大量用户的大问题.        因此,专业的测试人员,在对待

【转】支付场景测试应该考虑哪些方面

软件测试人员在进行测试的时候,根据测试项目或者测试对象的不同,会采用不同的方式方法来进行测试,那么,带有支付功能的产品该如何测试呢?在测试过程中又应该注意些什么?        财务人员有句老话叫:财务无小事.因为,首先,任何涉及到财务的问题,不论金额有多么的小,它在性质上也是严重事件:其次,在各种金融支付功能已深入老百姓生活的方方面面的今天,一个程序中,哪怕仅有一个小小的支付问题,那么,最后引起的也可能是涉及成百上千乃至上亿元金额和大量用户的大问题.        因此,专业的测试人员,在对待

微信小程序支付及退款流程详解

微信小程序的支付和退款流程 近期在做微信小程序时,涉及到了小程序的支付和退款流程,所以也大概的将这方面的东西看了一个遍,就在这篇博客里总结一下. 首先说明一下,微信小程序支付的主要逻辑集中在后端,前端只需携带支付所需的数据请求后端接口然后根据返回结果做相应成功失败处理即可.我在后端使用的是php,当然在这篇博客里我不打算贴一堆代码来说明支付的具体实现,而主要会侧重于整个支付的流程和一些细节方面的东西.所以使用其他后端语言的朋友有需要也是可以看一下的.很多时候开发的需求和相应问题的解决真的要跳出语

场景测试-支付场景

        财务人员有句老话叫:财务无小事.因为,首先,任何涉及到财务的问题,不论金额有多么的小,它在性质上也是严重事件:其次,在各种金融支付功能已深入老百姓生活的方方面面的今天,一个程序中,哪怕仅有一个小小的支付问题,那么,最后引起的也可能是涉及成百上千乃至上亿元金额和大量用户的大问题.         因此,专业的测试人员,在对待带有支付功能的产品时,都会格外的小心谨慎,将边界值分析.等价类划分.错误推测.因果图等各种测试方法进行结合,整理出尽可能全面的测试案例,对该支付功能及其相关功能

金融壹账通助力丹阳城商行实现“眨眼支付”

在丹阳市金保工程发卡过程中,丹阳市城商行就遇到了大量年龄偏大,无智能手机未使用支付宝和微信的老年群体.如何让老年人群也能享受随时随地的现代支付便利,这是问题一直是丹阳城商行董事长田贵荣心中的牵挂. 2018年9月20日,金融壹账通&平安科技助力丹阳城商行打造的"眨眼支付"发布会成功举办.丹阳市城商行董事长田贵荣.金融壹账通首席营销官孙家春.金融壹账通营销中心华东区负责人罗凌共同出席了本次发布会.本次发布会还有幸邀请到丹阳市政府多位.江苏省农村信用社联合社.×××镇江市中心支行.

微信支付PHP SDK —— 公众号支付代码详解

在微信支付 开发者文档页面 下载最新的 php SDK http://mch.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1 这里假设你已经申请完微信支付 1. 微信后台配置  如图 我们先进行测试,所以先把测试授权目录和 测试白名单添加上.测试授权目录是你要发起微信请求的哪个文件所在的目录. 例如jsapi 发起请求一般是jsapi.php所在目录 为测试目录,测试白名单即开发人员的微信号. 正式的支付授权目录不能和测试的一样否则会报错.不填

微信支付之JSAPI公众号支付

前提 本教程默认以下几点你已经完全满足: 开通了认证后的服务号 服务号开通的微信支付的认证 腾讯给你的邮件中有商户登录的账号和密码 拥有一个可供上传代码和设置回调域名的网站或云服务 有一点点php知识. 第一步:公众号设置 1. 你的公众号,在支付认证的标签下, 内容应该和下图类似.证明公众号已经完成了认证和合约的签署. 2. 然后在微信支付–开发配置中,设置测试授权目录和测试白名单 3. 在公众号设置-功能设置标签中,设置JS接口安全域名,这个域名在认证获取token的过程中可能会用到.但具体

微信支付错误两个问题的解决:curl出错,错误码:60

如下是运行微信支付测试代码时出错代码: Warning: curl_setopt() expects parameter 2 to be long, string given in D:\wwwroot\weixinpaytest\pay\WxPay.JsApiPay.php on line 99 Fatal error: Uncaught exception 'WxPayException' with message 'curl出错,错误码:60' in D:\wwwroot\weixinpa

H5版如何在微信外(非微信浏览器)进行微信支付技术方案

官方是支持在非微信内置浏览器中调起微信支付的!H5支付是基于公众号基础开发的一种非微信内浏览器支付方式(需要单独申请支付权限),可以满足在微信外的手机H5页面进行微信支付的需求.同时,由于H5链接传播十分方便.来源不易追踪,商户需要特别注意做好防钓鱼.防刷单的处理,控制风险. 流程原理 接口说明 (1)用户打开商户H5网页选购商品,生成支付订单:(2)商户调用[统一下单]接口(接口中trade_type需定义为WAP),获得预支付交易会话标识prepayid:(3)商户按照微信H5支付协议生成d