ios第三方支付-微信篇(含本地签名)

ios支付为内购和第三方支付微信,支付宝,银联

一微信支付
相关链接
微信开放平台
https://open.weixin.qq.com
微信支付商户平台
https://pay.weixin.qq.com/index.php/core/home/login?return_url=%2Findex.php
微信支付文档
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1
微信支付包地址和demo
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419319164&lang=zh_CN

//统一下单接口
@”https://api.mch.weixin.qq.com/pay/unifiedorder“//

流程:app发起支付请求->将用户设备号,网络ip,用户id,商品id等参数发送给WebServer
服务器->向微信支付服务器发送支付请求(要将相关参数排序签名加密)
微信支付服务器向->app服务器发送本次支付预支付 prePayID
服务器->根据预支付订单号进行二次签名将参数返回给客户端
客户端-调起微信-用户确认购买-》购买成功返回app
app-向服务器询问本次购买结果
这里有2种情况:服务器签名加密(推荐),客户端签名加密(不安全)
如果是服务器签名加密我们客户端接入比较剪短
只要上传相关参数给服务器然后接受服务器返回的参数跳转微信支付然后在支付结果里面查询本次结果就行了

1)项目配置
设置项目属性中的URL Schemes

1.1)导包两种选择pods和手动配置
pod ‘WechatOpenSDK’
手动导包
Linked Frameworks and Libraries 中添加相应内容
CFNetwork.framework
Seucrity.framework
coreTelephony.framework
systemconfiguration.framework
libz,dylib
libsqlite3.0.dylib
uikit.framework
Foundation.framework
1.2)代码
`@interface AppDelegate ()
- (BOOL)application:(UIApplication )application didFinishLaunchingWithOptions:(NSDictionary )launchOptions
{
//注册微信支付
[WXApi registerApp:MXWechatAPPID withDescription:@”微信支付”];

return YES;

}
`

pragma mark - 微信支付回调

`- (BOOL)application:(UIApplication )application handleOpenURL:(NSURL )url
{
return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
}

  • (BOOL)application:(UIApplication )application openURL:(NSURL )url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
    {
    return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
    }

// NOTE: 9.0以后使用新API接口
- (BOOL)application:(UIApplication )app openURL:(NSURL )url options:(NSDictionary

pragma mark — 创建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=%@", API_KEY];
NSLog(@"%@",contentString);
//得到MD5 sign签名
NSString *md5Sign =[self md5:contentString];

//输出Debug Info
//    [self.debugInfo appendFormat:@"MD5签名字符串:\n%@\n\n",contentString];

return md5Sign;

}`

pragma mark — 将字符串进行MD5加密,返回加密后的字符串

`-(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];

for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
    [output appendFormat:@"%02X", digest[i]];

return output;

}
向微信支付服务器发送请求并且解析(微信支付返回的是xml格式的数据需要转换)
AFHTTPSessionManager *session = [AFHTTPSessionManager manager];
session.responseSerializer = [[AFHTTPResponseSerializer alloc] init];
[session.requestSerializer setValue:@”text/xml; charset=utf-8” forHTTPHeaderField:@”Content-Type”];
[session.requestSerializer setValue:@”https://api.mch.weixin.qq.com/pay/unifiedorder” forHTTPHeaderField:@”SOAPAction”];

[session.requestSerializer setQueryStringSerializationWithBlock:^NSString *(NSURLRequest *request, NSDictionary *parameters, NSError *__autoreleasing *error) {
    return send;
}];

[session POST:@"https://api.mch.weixin.qq.com/pay/unifiedorder" parameters:send constructingBodyWithBlock:^(id  _Nonnull formData) {

} progress:^(NSProgress * _Nonnull uploadProgress) {

} success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {

    XMLHelper *xml  = [[XMLHelper alloc] init];
    //开始解析
    [xml startParse:responseObject];
    NSMutableDictionary *resParams = [xml getDict];
    NSLog(@"%@",resParams);
    //判断返回
    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"]) {

//预支付订单号
aprepayid = [resParams objectForKey:@”prepay_id”];
}
}
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {

}];

我们拿到了prepayid后进行二次签名
NSString *package, *time_stamp, *nonce_str;
//设置支付参数
time_t now;
time(&now);
time_stamp = [NSString stringWithFormat:@”%ld”, now];//时间戳
nonce_str = [self md5:time_stamp];//随机字符串(直接用时间戳来生成就可以了)

 package         = @"Sign=WXPay";

NSMutableDictionary *signParams = [NSMutableDictionary dictionary];//用于二次签名的参数
[signParams setObject: APP_KEY  forKey:@"appid"];
[signParams setObject: MCH_ID  forKey:@"partnerid"];
[signParams setObject: nonce_str    forKey:@"noncestr"];
[signParams setObject: package      forKey:@"package"];
[signParams setObject: time_stamp   forKey:@"timestamp"];
[signParams setObject: prePayID     forKey:@"prepayid"];

最后调用微信客户端进行支付
//调起微信支付
PayReq* req = [[PayReq alloc] init];
req.partnerId = MCH_ID;
req.prepayId = prePayID;
req.nonceStr = nonce_str;
req.timeStamp = time_stamp.intValue;
req.package = package;

req.sign                = [self createMd5Sign:signParams];//二次签名

[WXApi sendReq:req];`

demo—-https://github.com/missljl/WXPay

你可能感兴趣的:(#,iOS-扩展篇各种功能)