iOS開發之微信支付


服務器簽名版本

官方已經是建議使用服務器簽名來接入微信支付,實際上從安全上考慮,確實是每個客戶端不應該知道RAS密鑰,也不需要每個客戶端都寫一遍簽名的算法。

服務端接入流程文檔:https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=8_3

商戶系統和微信支付系統主要交互說明:

步驟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

1.導入SDK文件

2.導入相關的系統庫及文件。不導入會報錯。

  • SystemConfiguration.framework
  • libz.tbd 
  • libsqlite3.0.tbd
  • CoreTelephony.framework
  • libc++.tbd

3.配置info.plist

a.schemes ,注意,item0 這里要修改成商戶自己的APPID

或者這樣修改:

b.白名單

c.安全配置支持Http

當然這部分的配置,也可以通過修改XML來實現。

4.修改bitcode。

修改:

5.在AppDelegate 注冊微信

導入#import "WXApiManager.h"

復制代碼
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    //向微信注冊wxd930ea5d5a258f4f
    [WXApi registerApp:@"wxb4ba3c02aa476ea1" withDescription:@"demo 2.0"];
    
    return YES;
}

- (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]];
}
復制代碼

6.接下來,就是發起請求支付了,實現上核心代碼只有幾行。

這部分代碼在demo的WXApiRequestHandler--》jumpToBizPay 里。

復制代碼
                    //調起微信支付
                    PayReq* req             = [[[PayReq alloc] init]autorelease];
                    req.partnerId           = [dict objectForKey:@"partnerid"];
                    req.prepayId            = [dict objectForKey:@"prepayid"];
                    req.nonceStr            = [dict objectForKey:@"noncestr"];
                    req.timeStamp           = stamp.intValue;
                    req.package             = [dict objectForKey:@"package"];
                    req.sign                = [dict objectForKey:@"sign"];
                    [WXApi sendReq:req];
復制代碼

7.不管支付成功還是失敗,結果會返回到WXApiManager--》onResp 方法下

復制代碼
        switch (resp.errCode) {
            case WXSuccess:
                strMsg = @"支付結果:成功!";
                NSLog(@"支付成功-PaySuccess,retcode = %d", resp.errCode);
                break;
                
            default:
                strMsg = [NSString stringWithFormat:@"支付結果:失敗!retcode = %d, retstr = %@", resp.errCode,resp.errStr];
                NSLog(@"錯誤,retcode = %d, retstr = %@", resp.errCode,resp.errStr);
                break;
        }
復制代碼

我們直接處理回調結果即可。

客戶端進行簽名

1.導入文件。官方已經不提供這個SDK的下載了,我已經打包到源代碼了,2015年3月11號最新修改的版本

 

2.里面有兩個文件是非arc的,我們需要設置一下 -fno-objc-arc

3.導入系統庫及info.list配置,請參數上面服務端簽名。

4.AppDelegate配置

1)導入頭文件

#import "WXApi.h"
#import "payRequsestHandler.h"

2)實現微信代理

@interface AppDelegate ()<WXApiDelegate>

@end

3)注冊微信,及微信支付回調

復制代碼
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    //向微信注冊
    [WXApi registerApp:APP_ID withDescription:@"demo 2.0"];
    
    return YES;
}

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
    return  [WXApi handleOpenURL:url delegate:self];
}

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

// 微信支付成功或者失敗回調
-(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 = @"支付結果:成功!";
                NSLog(@"支付成功-PaySuccess,retcode = %d", resp.errCode);
                break;
                
            default:
                strMsg = [NSString stringWithFormat:@"支付結果:失敗!retcode = %d, retstr = %@", resp.errCode,resp.errStr];
                NSLog(@"錯誤,retcode = %d, retstr = %@", resp.errCode,resp.errStr);
                break;
        }
    }
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:strTitle message:strMsg delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
    [alert show];
}
復制代碼

5.寫方法直接在支付時調用

復制代碼
- (void)payForWechat
{
    //創建支付簽名對象
    payRequsestHandler *req = [[payRequsestHandler alloc] init];
    //初始化支付簽名對象
    [req init:APP_ID mch_id:MCH_ID];
    //設置密鑰
    [req setKey:PARTNER_ID];
    
    NSMutableDictionary *dict = [req sendPay_demo];
    
    if(dict != nil){
        NSMutableString *retcode = [dict objectForKey:@"retcode"];
        if (retcode.intValue == 0){
            NSMutableString *stamp  = [dict objectForKey:@"timestamp"];
            
            //調起微信支付
            PayReq* req             = [[PayReq alloc] init];
            req.openID              = [dict objectForKey:@"appid"];
            req.partnerId           = [dict objectForKey:@"partnerid"];
            req.prepayId            = [dict objectForKey:@"prepayid"];
            req.nonceStr            = [dict objectForKey:@"noncestr"];
            req.timeStamp           = stamp.intValue;
            req.package             = [dict objectForKey:@"package"];
            req.sign                = [dict objectForKey:@"sign"];
            [WXApi sendReq:req];
            //日志輸出
            NSLog(@"appid=%@\npartid=%@\nprepayid=%@\nnoncestr=%@\ntimestamp=%ld\npackage=%@\nsign=%@",req.openID,req.partnerId,req.prepayId,req.nonceStr,(long)req.timeStamp,req.package,req.sign );
        }else{
            [self alert:@"提示信息" msg:[dict objectForKey:@"retmsg"]];
        }
    }else{
        [self alert:@"提示信息" msg:@"服務器返回錯誤,未獲取到json對象"];
    }
}

//客戶端提示信息
- (void)alert:(NSString *)title msg:(NSString *)msg
{
    UIAlertView *alter = [[UIAlertView alloc] initWithTitle:title message:msg delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    
    [alter show];
}
復制代碼
注意:

微信在異步處理完成后一定會調用onResp,如果回調網址不能正常訪問,就無法返回商戶APP,所以無法正常調用onResp。(使用官方微信開發者ID就會出現這種現象)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM