实用技术——支付_微信

  • 与微信官方签署在线协议

  • 导入微信支付需要的SDK相关文件

  • 配置App跳转的白名单

  • 添加URL Schemes

  • 配置代码

    1. 在AppDelegate.m中向微信注册第三方应用
      //向微信终端程序注册第三方应用
      [WXApi registerApp:wexinAppId];
    2. 确保支付结果回调方法能够接受到,在AppDelegate.m中添加一下代码
      - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
      if([url.host isEqualToString:@"pay"]){
      return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
      }else{
      return YES;
      }
      }
      - (BOOL)application:(UIApplication *)application handleOpenURL:(nonnull NSURL *)url
      {
      if([url.host isEqualToString:@"pay"]){
      return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
      }else{
      return YES;
      }
      }
      - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{
      if([url.host isEqualToString:@"pay"]){
      return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
      }else{
      return YES;
      }
      }
    • 设置支付信息,调用微信支付
      NSMutableDictionary dict = [result[@"data"] objectAtIndex:0];
      //调起微信支付
      PayReq
      req = [[PayReq alloc] init];
      //由用户微信号和AppID组成的唯一标识
      req.openID = [dict objectForKey:@"appid"];
      //商家向财付通申请的商家id
      req.partnerId = [dict objectForKey:@"mch_id"];
      //预支付订单
      req.prepayId = [dict objectForKey:@"prepay_id"];
      //随机串,防重发
      req.nonceStr = [dict objectForKey:@"nonce_str"];
      //时间戳,防重发
      req.timeStamp = [[dict objectForKey:@"timeStamp"] intValue];
      //商家根据财付通文档填写的数据和签名
      req.package = @"Sign=WXPay";
      //商家根据微信开放平台文档对数据做的签名
      req.sign = [self getWeiXinPaySign:req];
      [WXApi sendReq:req];

    • 处理支付结果
      为了对支付结果可以进行不同的操作处理,可以创建一个单例对象来管理。
      #import <Foundation/Foundation.h>
      #import "WXApi.h"
      @protocol WXApiManagerDelegate <NSObject>
      @optional
      - (void)managerDidRecvPayForSuccessResponse:(PayResp *)response;

      - (void)managerDidRecvPayForFailResponse:(PayResp *)response;
      @end
      
      @interface WXApiManager : NSObject<WXApiDelegate>
      @property (nonatomic, assign) id<WXApiManagerDelegate> delegate;
      + (instancetype)sharedManager;
      @end
      
      #import "WXApiManager.h"
      @implementation WXApiManager
      
      #pragma mark - LifeCycle
      +(instancetype)sharedManager {
        static dispatch_once_t onceToken;
        static WXApiManager *instance;
        dispatch_once(&onceToken, ^{
        instance = [[WXApiManager alloc] init];
        });
      return instance;
      }
      
      - (void)dealloc {
        self.delegate = nil;
        [super dealloc];
      }
      
      #pragma mark - WXApiDelegate
      - (void)onResp:(BaseResp *)resp {
          if([resp isKindOfClass:[PayResp class]]){
              switch (resp.errCode) {
                  case WXSuccess:
                  {
                      if (_delegate && [_delegate respondsToSelector:@selector(managerDidRecvPayForSuccessResponse:)]) {
                      PayResp *payResp = (PayResp *)resp;
                      [_delegate managerDidRecvPayForSuccessResponse:payResp];
              }
          }
              break;
              
          default:
              if (_delegate && [_delegate respondsToSelector:@selector(managerDidRecvPayForFailResponse:)]) {
                  PayResp *payResp = (PayResp *)resp;
                  [_delegate managerDidRecvPayForFailResponse:payResp];
              }
              break;
          }
        }
      }
      @end
      
    • 签名sign生成方法
      //获取微信签名
      -(NSString)getWeiXinPaySign:(PayReq)req
      {
      NSMutableDictionary *signParams = [NSMutableDictionary dictionary];
      [signParams setObject: req.openID forKey:@"appid"];
      [signParams setObject: req.nonceStr forKey:@"noncestr"];
      [signParams setObject: req.package forKey:@"package"];
      [signParams setObject: req.partnerId forKey:@"partnerid"];
      [signParams setObject: [NSString stringWithFormat:@"%u",(unsigned int)req.timeStamp] forKey:@"timestamp"];
      [signParams setObject: req.prepayId forKey:@"prepayid"];
      //生成签名
      NSString *sign = [self createMd5Sign:signParams];
      return sign;
      }

      //创建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) {
              if (![[dict objectForKey:categoryId] isEqualToString:@""] &&
                  ![categoryId isEqualToString:@"sign"] &&
                  ![categoryId isEqualToString:@"key"]){
              
                  [contentString appendFormat:@"%@=%@&", categoryId, [dict objectForKey:categoryId]];
                 }
              }
          //添加key字段,商户密钥
          [contentString appendFormat:@"key=%@", @"xxxxxxxxxxx"];
          //得到MD5 sign签名
          NSString *md5Sign =[WXUtil md5:contentString];
          return md5Sign;
        }
      //md5 encode
      +(NSString *) md5:(NSString *)str
      {
          const char *cStr = [str UTF8String];
          unsigned char digest[CC_MD5_DIGEST_LENGTH];
          CC_MD5( cStr, (unsigned int)strlen(cStr), digest );
      
          NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
          //这里的x是小写则产生的md5也是小写,是大写则产生的md5是大写
          for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
              [output appendFormat:@"%02X", digest[i]];
      
          return output;
      }
      
  • 注意事项:

    1. 签名Sign一定得进行MD5加密,格式严格按照微信官方方式加密。
      prepayId(预支付订单)失效、过期。
      如果出现上述问题(一般是参数错误),就会造成调起微信支付,只出现一个确定按钮
    • 支付结果无法获取回调?
      确保第四步的b步骤是否实现
    • 如果APP里面使用了友盟或者ShareSDK做分享,那就不用再导入SDK了,否则会出现一些诡异的问题,
      例如无法调起手机微信客户端、无法调起微信客户端web页面,调起了但是一闪而过。这都基本上都是因为分享的SDK里面已经包括了微信的SDK。所以如果出现诡异的错误了看看是不是两个冲突了。
    • 如果你用了友盟社会化分享来做微信登录的话,那么你要先用友盟注册微信,后调用微信SDK注册
      [UMSocialWechatHandlersetWXAppId:SHappSecret:SH url:SHAREURL];
      [WXApiregisterApp:SHARE_WX withDescription:@"demo"];
    • 微信无法调起
      未安装微信、未将微信加入白名单
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容

  • iOS支付 iOS支付分为两类,第三方支付和应用内支付(内购)。 第三方支付包括:支付宝支付、微信支付、银联支付、...
    请输入账号名阅读 6,173评论 3 22
  • 官方建议使用服务器签名来接入微信支付,从安全上考虑,客户端不应该知道RAS密钥,也不需要每个客户端都写一遍签名的算...
    wpf_register阅读 485评论 0 2
  • 01 木子说来世她一定要做一棵安静的树,开心时开花,难过时落叶。她就可以再也不用理会尘世间的那些纷纷扰扰了。 木子...
    爱上世界的张大路阅读 587评论 8 14
  • 清晨五点,就已醒来,昨晚打球身体疲乏,睡眠质量不高,醒来又进行了剧烈的运动,消耗了不少的体力,致使闹钟的呼喊我还是...
    江流_ddba阅读 164评论 0 0