iOS开发之第三方支付微信支付教程,史上最新最全第三方微信支付方式实现、微信集成教程,微信实现流程

本章项目demo: https://github.com/zhonggaorong/weixinLoginDemo


本章不讲解: 微信sdk的集成 , 项目集成的文章请参照 (包含微信登录):   http://blog.csdn.net/zhonggaorong/article/details/51719050


 1. 微信支付微信支付前奏大致流程为 :

1. 公司需要到微信进行申请app支付功能 , 获得appid和微信支付商户号(mch_id)和API秘钥(key) 、 Appsecret(secret,开发中用到的,很重要

  1. appidappid是微信公众账号或开放平台APP的唯一标识,在公众平台申请公众账号或者在开放平台申请APP账号后,微信会自动分配对应的appid,用于标识该应用。可在微信公众平台-->开发者中心查看,商户的微信支付审核通过邮件中也会包含该字段值。
  2. 微信支付商户号:商户申请微信支付后,由微信支付分配的商户收款账号。
  3. API密钥: 交易过程生成签名的密钥,仅保留在商户系统和微信支付后台,不会在网络中传播。商户妥善保管该Key,切勿在网络中传输,不能在其他客户端中存储,保证key不会被泄漏。商户可根据邮件提示登录微信商户平台进行设置。也可按一下路径设置:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置
  4. App secret : AppSecret是APPID对应的接口密码,用于获取接口调用凭证access_token时使用。
  5. 详情请参考这个网址:  https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=3_1

2.  下载微信SDK : https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=11_1 

      还有Demo地址.


3.   根据上面的集成教程地址 ,搭建好项目

4.   设置好URL Types ,(具体怎么设置也在环境搭建的文章中说到了,请大家注意看)。

5.    记得把网络从https 改变成为 http。 

6. 设置微信白名单 。 


7. 现在基本就是环境搭配完毕了。 


2. 微信支付具体流程如下:

1. 流程图一览


2. 具体流程

步骤1:用户在商户APP中选择商品,提交订单,选择微信支付。
步骤2:商户后台收到用户支付单,调用微信支付统一下单接口。参见【统一下单API】。
步骤3:统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP。参与签名的字段名为appId,partnerId,prepayId,nonceStr,timeStamp,package。注意:package的值格式为Sign=WXPay
步骤4:商户APP调起微信支付。api参见本章节【app端开发步骤说明】
步骤5:商户后台接收支付通知。api参见【支付结果通知API】
步骤6:商户后台查询支付结果。,api参见【查询订单API】


3.开发前需要注意的几个方面。

1. 微信规定的规则,必须遵循,不然可能导致不能让微信支付成功。参照网址: https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=4_1 

2. 微信订单支付 ,参数规定 :  参照网址 : https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=4_2

3. 微信订单 ,参数的拼接, 签名的算法、 以及相关证书的详细讲解 : 参照网址: https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=4_3

特别注意以下重要规则:
◆ 参数名ASCII码从小到大排序(字典序);
◆ 如果参数的值为空不参与签名;
◆ 参数名区分大小写;
◆ 验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。
◆ 微信接口可能增加字段,验证签名时必须支持增加的扩展字段

开发参照微信官方api 地址 : https://open.weixin.qq.com/zh_CN/htmledition/res/dev/document/sdk/ios/interface_w_x_app_extend_object.html

微信开发 支付 签名参数校验: https://pay.weixin.qq.com/wiki/tools/signverify/

4. 具体的客户端开发过程:

步骤1:用户进入商户APP,选择商品下单、确认购买,进入支付环节。商户服务后台生成支付订单,签名后将数据传输到APP端,可参照官方支付demo。  https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=11_1
步骤2:用户点击后发起支付操作,进入到微信界面,调起微信支付,出现确认支付界面,。
步骤3:用户确认收款方和金额,点击立即支付后出现输入密码界面,可选择零钱或银行卡支付.
第四步:输入正确密码后,支付完成,用户端微信出现支付详情页面。
第五步:回跳到商户APP中,商户APP根据支付结果个性化展示订单处理结果.



5. 正式编程 。

1. 再次确认url schemes中设置 APPID , 商户在微信开放平台申请开发APP应用后,微信开放平台会生成APP的唯一标识APPID。在Xcode中打开项目,设置项目属性中的URL Schemes为您的APPID。

2.  商户APP工程中引入微信lib库和头文件,调用API前,需要先向微信注册您的APPID,代码如下:[WXApi registerApp:@"wxd930ea5d5a258f4f" withDescription:@"123"];


3. 调起微信支付 (参数拼接, 签名)


4 支付结果回调 



核心代码展示 : 

回调方法展示:

appdelegate.m

/*! 微信回调,不管是登录还是分享成功与否,都是走这个方法 @brief 发送一个sendReq后,收到微信的回应
 *
 * 收到一个来自微信的处理结果。调用一次sendReq后会收到onResp。
 * 可能收到的处理结果有SendMessageToWXResp、SendAuthResp等。
 * @param resp具体的回应内容,是自动释放的
 */
-(void) onResp:(BaseResp*)resp{
    NSLog(@"resp %d",resp.errCode);
    
    /*
    enum  WXErrCode {
        WXSuccess           = 0,    成功
        WXErrCodeCommon     = -1,  普通错误类型
        WXErrCodeUserCancel = -2,    用户点击取消并返回
        WXErrCodeSentFail   = -3,   发送失败
        WXErrCodeAuthDeny   = -4,    授权失败
        WXErrCodeUnsupport  = -5,   微信不支持
    };
    */
    if ([resp isKindOfClass:[SendAuthResp class]]) {   //授权登录的类。
        if (resp.errCode == 0) {  //成功。
            //这里处理回调的方法 。 通过代理吧对应的登录消息传送过去。
            if ([_wxDelegate respondsToSelector:@selector(loginSuccessByCode:)]) {
                SendAuthResp *resp2 = (SendAuthResp *)resp;
                [_wxDelegate loginSuccessByCode:resp2.code];
            }
        }else{ //失败
            NSLog(@"error %@",resp.errStr);
            UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"登录失败" message:[NSString stringWithFormat:@"reason : %@",resp.errStr] delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
            [alert show];
        }
    }
    
    if ([resp isKindOfClass:[SendMessageToWXResp class]]) { //微信分享 微信回应给第三方应用程序的类
        SendMessageToWXResp *response = (SendMessageToWXResp *)resp;
        NSLog(@"error code %d  error msg %@  lang %@   country %@",response.errCode,response.errStr,response.lang,response.country);
        
        if (resp.errCode == 0) {  //成功。
            //这里处理回调的方法 。 通过代理吧对应的登录消息传送过去。
            if (_wxDelegate) {
                if([_wxDelegate respondsToSelector:@selector(shareSuccessByCode:)]){
                    [_wxDelegate shareSuccessByCode:response.errCode];
                }
            }
        }else{ //失败
            NSLog(@"error %@",resp.errStr);
            UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"分享失败" message:[NSString stringWithFormat:@"reason : %@",resp.errStr] delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
            [alert show];
        }
    }
    
    /*
    0  展示成功页面
    -1  可能的原因:签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常等。
    -2  用户取消	无需处理。发生场景:用户不支付了,点击取消,返回APP。
     */
    if ([resp isKindOfClass:[PayResp class]]) { // 微信支付
        
        PayResp*response=(PayResp*)resp;
        switch(response.errCode){
            case 0:
                //服务器端查询支付通知或查询API返回的结果再提示成功
                NSLog(@"支付成功");
                break;
                
            default:
                NSLog(@"支付失败,retcode=%d  errormsg %@",resp.errCode ,resp.errStr);
                break;
        }
    }
}

方法调用。

viewController.m方法

#pragma mark 微信支付
- (IBAction)weixinPayAction:(id)sender {
    
    
    /**
     *  外界调用的微信支付方法
     *
     *  @param ordeNumber  系统下发订单号%100000000 得出的数字,确保唯一。
     *  @param myNumber    订单号  确保唯一
     *  @param price       价格
     付款流程:
     
     1. 获取 AccessToken
     2. 获取 genPackage
     3. 调起微信付款
     4. 在appdelegate 中的 onResp 监听 回调方法。 看是付款成功。
     
     回调代码参数说明:
     0  展示成功页面
     -1  可能的原因:签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常等。
     -2  用户取消	无需处理。发生场景:用户不支付了,点击取消,返回APP。
     */

    helper = [[WeixinPayHelper alloc] init];
    [helper payProductWith:@"Test Product" andName:@"product number 1" andPrice:[NSString stringWithFormat:@"%d",1500]];
    
}


封装的核心支付工具类方法

WeixinPayHelper.h

//
//  WeixinPayHelper.h
//  weixinLoginDemo
//
//  Created by 张国荣 on 16/7/1.
//  Copyright © 2016年 BateOrganization. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "WXApi.h"
#import "AFNetworking.h"
/**
 *  微信支付工具类
 */
@interface WeixinPayHelper : NSObject
@property (nonatomic, strong) AFHTTPSessionManager *request;
@property (nonatomic, copy) NSString *timeStamp;
@property (nonatomic, copy) NSString *nonceStr;
@property (nonatomic, copy) NSString *traceId;
@property (nonatomic, copy) NSString *orderId;
@property (nonatomic, copy) NSString *orderPrice;
@property (nonatomic, copy) NSString *orderAllId;
+ (instancetype)shareInstance;


/**
 *  外界调用的微信支付方法
 *
 *  @param ordeNumber  系统下发订单号%100000000 得出的数字,确保唯一。
 *  @param myNumber    订单号  确保唯一
 *  @param price       价格
 付款流程:
 
  1. 获取 AccessToken
  2. 获取 PrepayId 、 包含参数拼接,签名、genPackage等
  3. 调起微信付款
  4. 在appdelegate 中的 onResp 监听 回调方法。 看是付款成功。
 
 回调代码参数说明:
 0  展示成功页面
 -1  可能的原因:签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常等。
 -2  用户取消	无需处理。发生场景:用户不支付了,点击取消,返回APP。
 */
- (void)payProductWith:(NSString*)ordeNumber andName:(NSString*)myNumber andPrice:(NSString*)price;

@end


WeixinPayHelper.m

//
//  WeixinPayHelper.m
//  weixinLoginDemo
//
//  Created by 张国荣 on 16/7/1.
//  Copyright © 2016年 BateOrganization. All rights reserved.
//

#import "WeixinPayHelper.h"
#import "CommonUtil.h"
#import "Constant.h"

#define ISOFTEN_WECHARPAY_URL            @"https://www.sizzee.com/tenpay/payment/mobilesuccess"

@interface WeixinPayHelper()

@end

@implementation WeixinPayHelper

NSString *AccessTokenKey = @"access_token";
NSString *PrePayIdKey = @"prepayid";
NSString *errcodeKey = @"errcode";
NSString *errmsgKey = @"errmsg";
NSString *expiresInKey = @"expires_in";

/**
 *  微信开放平台申请得到的 appid, 需要同时添加在 URL schema
 */
NSString * const WXAppId = @"app id";
/**
 * 微信开放平台和商户约定的支付密钥
 *
 * 注意:不能hardcode在客户端,建议genSign这个过程由服务器端完成
 */
NSString * const WXAppKey = @"appkey";

/**
 * 微信开放平台和商户约定的密钥
 *
 * 注意:不能hardcode在客户端,建议genSign这个过程由服务器端完成
 */
NSString * const WXAppSecret = @"app Secret";

/**
 * 微信开放平台和商户约定的支付密钥
 *
 * 注意:不能hardcode在客户端,建议genSign这个过程由服务器端完成
 */
NSString * const WXPartnerKey = @"秘钥、 放服务器的,这儿方便演示";
/**
 *  微信公众平台商户模块生成的ID
 */
NSString * const WXPartnerId = @"商户id";


+ (instancetype)shareInstance
{
    static WeixinPayHelper *sharedClient = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedClient = [[WeixinPayHelper  alloc] init];
    });
    return sharedClient;
}
/**
 *  外界调起微信下单的方法
 *
 *  @param ordeNumber 订单号 ,由服务器下发、经过处理的  生成genPackage 需要用到
 *  @param myNumber   订单号 ,由服务器下发  生成genPackage 需要用到
 *  @param price      商品价格   生成genPackage 需要用到
 
 
 
 */
- (void)payProductWith:(NSString *)ordeNumber andName:(NSString *)myNumber andPrice:(NSString *)price{
    self.orderId = ordeNumber;
    self.orderPrice = price;
    self.orderAllId = myNumber;
    [self getAccessToken];
}

#pragma mark - 生成各种参数

#pragma mark 时间戳 生成
- (NSString *)genTimeStamp
{
    return [NSString stringWithFormat:@"%.0f", [[NSDate date] timeIntervalSince1970]];
}

/**
 * 注意:商户系统内部的订单号,32个字符内、可包含字母,确保在商户系统唯一
 */
- (NSString *)genNonceStr
{
    return [CommonUtil md5:[NSString stringWithFormat:@"%d", arc4random() % 10000]];
}

/**
 * 建议 traceid 字段包含用户信息及订单信息,方便后续对订单状态的查询和跟踪
 */
- (NSString *)genTraceId
{
    return [NSString stringWithFormat:@"crestxu_%@", [self genTimeStamp]];
}

- (NSString *)genOutTradNo
{
    return [CommonUtil md5:[NSString stringWithFormat:@"%d", arc4random() % 10000]];
}

#pragma mark genPackage 这个应该是服务器完成。 在这儿方便演示。
- (NSString *)genPackage
{
    // 构造参数列表
    NSMutableDictionary *params = [NSMutableDictionary dictionary];
    [params setObject:@"WX" forKey:@"bank_type"];
    [params setObject:[NSString stringWithFormat:@"拾裳%@订单", self.orderAllId] forKey:@"body"];
    [params setObject:@"1" forKey:@"fee_type"];
    [params setObject:@"UTF-8" forKey:@"input_charset"];
    [params setObject:ISOFTEN_WECHARPAY_URL forKey:@"notify_url"];
    [params setObject:[self genOutTradNo] forKey:@"out_trade_no"];
    [params setObject:WXPartnerId forKey:@"partner"];
    [params setObject:[CommonUtil getIPAddress:YES] forKey:@"spbill_create_ip"];
    [params setObject:self.orderPrice forKey:@"total_fee"];    // 1 == ¥0.01
    NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL:[[NSURL URLWithString:@"https://www.sizzee.com"] absoluteURL]];
    NSHTTPCookie *cookie;
    NSMutableArray* arr=[NSMutableArray array];
    for (cookie in cookies) {
        if (![cookie.name isEqualToString:@"app_code"]) {
            NSString* str=[NSString stringWithFormat:@"%@||%@",cookie.name,cookie.value];
            [arr addObject:str];
        }
    }
    
    
    NSString* aa=[arr componentsJoinedByString:@"||"];
    [params setObject:[NSString stringWithFormat:@"%@||%@||%@",self.orderId,[CommonUtil md5:[NSString stringWithFormat:@"1219929601fef54y3d5wsxf5yu55t5g5d5e35yujki%@",self.orderId]],aa] forKey:@"attach"];
    
    NSArray *keys = [params allKeys];
    NSArray *sortedKeys = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
        return [obj1 compare:obj2 options:NSNumericSearch];
    }];
    
    // 生成 packageSign
    NSMutableString *package = [NSMutableString string];
    for (NSString *key in sortedKeys) {
        [package appendString:key];
        [package appendString:@"="];
        [package appendString:[params objectForKey:key]];
        [package appendString:@"&"];
    }
    
    [package appendString:@"key="];
    [package appendString:WXPartnerKey]; // 注意:不能hardcode在客户端,建议genPackage这个过程都由服务器端完成
    
    // 进行md5摘要前,params内容为原始内容,未经过url encode处理
    NSString *packageSign = [[CommonUtil md5:[package copy]] uppercaseString];
    package = nil;
    
    // 生成 packageParamsString
    NSString *value = nil;
    package = [NSMutableString string];
    for (NSString *key in sortedKeys) {
        [package appendString:key];
        [package appendString:@"="];
        value = [params objectForKey:key];
        
        // 对所有键值对中的 value 进行 urlencode 转码
        value = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)value, nil, (CFStringRef)@"!*'&=();:@+$,/?%#[]", kCFStringEncodingUTF8));
        
        [package appendString:value];
        [package appendString:@"&"];
    }
    NSString *packageParamsString = [package substringWithRange:NSMakeRange(0, package.length - 1)];
    
    NSString *result = [NSString stringWithFormat:@"%@&sign=%@", packageParamsString, packageSign];
    
    
    
    return result;
}

- (NSString *)genSign:(NSDictionary *)signParams
{
    // 排序
    NSArray *keys = [signParams allKeys];
    NSArray *sortedKeys = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
        return [obj1 compare:obj2 options:NSNumericSearch];
    }];
    
    // 生成
    NSMutableString *sign = [NSMutableString string];
    for (NSString *key in sortedKeys) {
        [sign appendString:key];
        [sign appendString:@"="];
        [sign appendString:[signParams objectForKey:key]];
        [sign appendString:@"&"];
    }
    NSString *signString = [[sign copy] substringWithRange:NSMakeRange(0, sign.length - 1)];
    
    NSString *result = [CommonUtil sha1:signString];
    
    return result;
}

- (NSMutableDictionary *)getProductArgs
{
    self.timeStamp = [self genTimeStamp];
    self.nonceStr = [self genNonceStr]; // traceId 由开发者自定义,可用于订单的查询与跟踪,建议根据支付用户信息生成此id
    self.traceId = [self genTraceId];
    
    NSMutableDictionary *params = [NSMutableDictionary dictionary];
    [params setObject:WXAppId forKey:@"appid"];
    [params setObject:WXAppKey forKey:@"appkey"];
    [params setObject:self.timeStamp forKey:@"noncestr"];
    [params setObject:self.timeStamp forKey:@"timestamp"];
    [params setObject:self.traceId forKey:@"traceid"];
    [params setObject:[self genPackage] forKey:@"package"];
    [params setObject:[self genSign:params] forKey:@"app_signature"];
    [params setObject:@"sha1" forKey:@"sign_method"];
    
    NSError *error = nil;
//    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params options:NSJSONWritingPrettyPrinted error: &error];
    
    return params;
}

#pragma mark - 主体流程 - 获取 accessToken , 然后调用再拿着accessToken调用微信的支付接口。
- (void)getAccessToken
{
    //字段
    NSString *getAccessTokenUrl = [NSString stringWithFormat:@"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%@&secret=%@", WXAppId, WXAppSecret];

    self.request = [AFHTTPSessionManager manager];
    
    
    __weak WeixinPayHelper *weakSelf = self;
    self.request.requestSerializer = [AFJSONRequestSerializer serializer];//请求
    self.request.responseSerializer = [AFHTTPResponseSerializer serializer];//响应
    self.request.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html",@"application/json", @"text/json",@"text/plain", nil];

    [self.request POST:getAccessTokenUrl parameters:nil progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
         NSError *error = nil;
        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions                           error:&error];
        if (error) {
            [weakSelf showAlertWithTitle:@"错误" msg:@"获取 AccessToken 失败"];
            return;
        }
        NSString *accessToken = dict[AccessTokenKey];
        if (accessToken) {
            __strong WeixinPayHelper *strongSelf = weakSelf;
            [strongSelf getPrepayId:accessToken];
        } else {
            NSString *strMsg = [NSString stringWithFormat:@"errcode: %@, errmsg:%@", dict[errcodeKey], dict[errmsgKey]];
            [weakSelf showAlertWithTitle:@"错误" msg:strMsg];
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [weakSelf showAlertWithTitle:@"错误" msg:@"获取 AccessToken 失败"];

    }];
    
}

#pragma mark 根据accessToken 获取 PrePayID . 然后进行下单。

- (void)getPrepayId:(NSString *)accessToken
{
    
    NSString *getPrepayIdUrl = [NSString stringWithFormat:@"https://api.weixin.qq.com/pay/genprepay?access_token=%@", accessToken];

    NSMutableDictionary *postData = [self getProductArgs];
    __weak WeixinPayHelper *weakSelf = self;
    
    self.request = [AFHTTPSessionManager manager];
    self.request.requestSerializer = [AFJSONRequestSerializer serializer];//请求
    self.request.responseSerializer = [AFHTTPResponseSerializer serializer];//响应
    self.request.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html",@"application/json", @"text/json",@"text/plain", nil];

    [self.request POST:getPrepayIdUrl parameters:postData progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSError *error = nil;
        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:responseObject options:kNilOptions  error:&error];
        if (error) {
            [weakSelf showAlertWithTitle:@"错误" msg:@"获取 PrePayId 失败"];
            return;
        }
        
        NSString *prePayId = dict[PrePayIdKey];
        if (prePayId) {
            // 调起微信支付
            PayReq *request   = [[PayReq alloc] init];
            request.partnerId = WXPartnerId;
            request.prepayId  = prePayId;
            request.package   = @"Sign=WXPay";      // 文档为 `Request.package = _package;` , 但如果填写上面生成的 `package` 将不能支付成功
            request.nonceStr  = weakSelf.nonceStr;
            request.timeStamp = [weakSelf.timeStamp longLongValue];
            
            // 构造参数列表
            NSMutableDictionary *params = [NSMutableDictionary dictionary];
            [params setObject:WXAppId forKey:@"appid"];
            [params setObject:WXAppKey forKey:@"appkey"];
            [params setObject:request.nonceStr forKey:@"noncestr"];
            [params setObject:request.package forKey:@"package"];
            [params setObject:request.partnerId forKey:@"partnerid"];
            [params setObject:request.prepayId forKey:@"prepayid"];
            [params setObject:weakSelf.timeStamp forKey:@"timestamp"];
            request.sign = [weakSelf genSign:params];
            
            // 在支付之前,如果应用没有注册到微信,应该先调用 [WXApi registerApp:appId] 将应用注册到微信
            [WXApi sendReq:request];
            
        } else {
            NSString *strMsg = [NSString stringWithFormat:@"errcode: %@, errmsg:%@", dict[errcodeKey], dict[errmsgKey]];
            [weakSelf showAlertWithTitle:@"错误" msg:strMsg];
        }
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
         [weakSelf showAlertWithTitle:@"错误" msg:@"获取 PrePayId 失败"];
    }];
   
}

#pragma mark - Alert

- (void)showAlertWithTitle:(NSString *)title msg:(NSString *)msg
{
    UIAlertView *alert = [[UIAlertView alloc]initWithTitle:title message: msg delegate: self cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
    [alert show];

}
@end


总结:

 我这里付款做的比官方的demo做的复杂了很多, 做了很多服务器要做的事情,比如说 签名算法 、 以及参数按照key=value的格式 、 拼接秘钥 等。 

我介意没有特殊要求的朋友,就稍微看看,不必自己再操作一遍。  大家多去看看官方的api,上面讲的很详细。 


  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值