基於微信的SDK的學習與使用——實現產品支付


聲明本篇博客為作者原創,本篇是繼支付寶支付之后本人又學習的第二種支付實現,本篇着重於原理與注意事項的學習。

參考  參考 

微信支付的開發文檔相比支付寶的比較簡單,但是使用功能絲毫也不含糊,我覺得簡單易讀的文檔是吸引開發者做出喜好選擇的第一步。但是個人覺得,微信支付與支付寶的支付的實現思路大致雷同,並不能說是微信另開思路進行支付創新。

微信支付的官方文檔中提供了掃碼支付、公眾號支付、App支付支付模式。開發者要實現用微信支付的功能,需要商戶向微信官方申請微信支付權限,商戶獲得權限后,將支付賬戶信息告訴開發者。

商戶申請的支付賬號信息表如下:

 好了下面將要卻別兩個概念,什么是公眾號?什么是開放平台?

參考 公眾賬號就是面向企業、團體、機構、公司、政府等等的擁有一定運營能力一個團結的集合的公眾號,用來作為一個自媒體或者服務窗口來用,強調信息流。開放平台是面向那些擁有成熟的應用程序,能夠將信息分享給社交圈子的一種偏向技術實現的平台,是面向開發者來說。看看shareSDK中都能夠分享到的一些社交平台都是一種開放平台。個人理解。

微信支付的模式有:(參考)刷卡支付、掃碼支付、公眾號支付、App支付

刷卡支付:(非驗密支付)門店收銀台生成訂單->用戶打開客戶端生成支付條碼->門店掃碼->后台生成sign->后台調用刷卡API請求支付->微信支付系統驗證支付信息->通過驗證處理數據->給商戶后台->商戶后台對得到的支付結果進行簽名驗證和處理->{處理成功:微信支付系統會將支付結果返回給商戶,同時把支付結果通知給用戶(以短信、微信消息的形式通知)}
(驗密支付)門店收銀台生成訂單->向后台發起支付請求->后台調用【提交刷卡支付API】請求支付生成支付交易->微信支付系統驗證請求支付信息驗證->通過驗證要求用戶輸入密碼->微信支付系統返回USERPAYING狀態->給商戶后台返回收銀台應答結果->微支付系統通知用戶輸入密碼->用戶輸入密碼,提交微信支付,萬成支付->微信客戶端提示微信后台返回在支付結果->用戶得到來自微信后台的提示短息->商戶收銀台得到USERPAYING狀態經過商戶后台調用【查詢訂單API】查詢實際支付結果->如果支付結果仍為USERPAYING,則每隔5秒循環調用【查詢訂單API】判斷實際支付結果,如果用戶取消支付或累計30秒用戶都未支付,商戶收銀台退出查詢流程后繼續調用【撤銷訂單API】撤銷支付交易。

支付的異常處理:

用戶遇到支付異常,請按如下說明處理

(1)用戶微信端彈出系統錯誤提示框,用戶可在交易列表查看交易情況,如果未找到訂單,需要商戶重新發起支付交易;如果訂單顯示成功支付,商戶收銀系統再次調用【查詢訂單API】查詢實際支付結果;

(2)用戶微信端彈出支付失敗提示,例如:余額不足,信用卡失效。需要重新發起支付;

(3)當交易超時或支付交易失敗,商戶收銀系統必須調用【撤銷訂單API】,撤銷此交易。

(4)由於銀行系統異常、用戶余額不足、不支持用戶卡種等原因使當前支付交易失敗,商戶收銀系統應該把錯誤提示明確展示給收銀員。

(5)根據返回的錯誤碼,判斷是否需要撤銷交易,具體詳見API返回錯誤碼列表

 

下面是微信支付的協議規則:

微信支付也要使用到簽名(加密)

關於簽名:

第一步生成簽名:

(1)生成簽名,在生成簽名之前,與支付寶的一樣,也是要將訂單的信心以URL鍵值對的格式即key1=value1&key2=value2…)拼接成字符串stringA。對於該鍵值對要進行排序,按照(參數名ASII碼排序,就是第一個字母排序,如果首字母相同,就對第二個字母進行排序,依次排序....)

(2)不對空的鍵值對進行簽名,在准備訂單信息的時候如出現空值,則該空值對應的鍵不被簽名

(3)參數有大小寫之分,並且鍵 sign 不參與簽名

(4)如果訂單中除了微信給出的字段,又增添若干字段,

第二步得到臨時sign:

在stringA最后拼接上key得到stringSignTemp字符串,並對stringSignTemp進行MD5運算,再將得到的字符串所有字符轉換為大寫,得到sign值signValue。

key設置路徑:微信商戶平台(pay.weixin.qq.com)-->賬戶設置-->API安全-->密鑰設置

樣例參照官方文檔:參照  如何使用在線簽名驗證的操作:參照

在官方文檔中說明 “生成個隨機數算法”  有這樣一句話:字段nonce_str,主要保證簽名不可預測。我覺得這與支付寶中的:時間戳、隨機串都是要實現一樣的功能,增加簽名的復雜性與唯一性。微信這個nonce_str就相當於支付寶的Order.h中聲明的時間戳屬性字段。

在微信中凡是涉及資金的接口都需要獲取商戶的證書。如:資金回滾、退款、撤銷接口。

關於商戶證書:參考 就支付寶簽名要用到的公鑰與私鑰與微信的簽名機制比較,微信是采用的是證書機制,首先在商戶服務器上部署微信根證書,私鑰包含在證書里面,要想對訂單信息進行簽名,就需要對證書進行驗證,由於根證書放在商戶的有訪問權限控制的非虛擬目錄中(防止非法下載,防止病毒木馬,他人非法盜取),所以不論是請求還是回調都要使用https安全的傳輸協議。

 注意事項:微信官方文檔建議商戶使用較高版本的微信SSL、建議在調用支付API時,使用IPV4解析 參考

微信關於支付這一塊提供的官方接口主要有:提交刷卡支付API查詢訂單API撤銷訂單API申請退款API查詢退款下載對賬單API轉換短連接API授權碼查詢API

要使用微信支付前,必須要仔細閱讀官方文檔,要做到對上面的API的各種參數了解,明白怎么使用,也要注意文檔中的注意事項。

 有可能官方的SDK會修改,文檔會變動,所以還是要及時關注官方的文檔去學習。在我的下一篇博客中我會去重點寫一下使用微信支付的SDK環境搭建,以及如何從微信的官方demo中抽出有用的組件到我們的工程中。關於主要的參數本篇不再贅述。

 

下面僅僅是模擬微信支付的實現,因為微信支付是在微信這個App中不存在調用網頁支付。所以本文不能看到支付的界面。

首先建立一個新的工程作為我們的工程,工程名字為weixin_study

 使用故事版為其關聯一個支付的按鈕,按鈕名字為:weixinPay_Button

(1)注冊微信的開放平台申請Appid 注冊

這里注冊的測試 Appid 是 “wx920fde9f97d60569”

在工程->info->URL Types 中作如下配置

 

(2)從官網得到的demo中取出名字為 “SDKExport” 的文件夾拖入我們的工程中

(2)在工程->Build Phases->Link Binary With Libraries 中引入下面組件

致此支付的環境已經配置好了,下面實現支付的功能

我們模擬的訂單信息是:

{
"status": 200,
"message": "成功!",
"data": {
"payId": 14187,
"orderId": 16257,
"orderNo": "2016011215151844904636",
"amount": 300,
"name": "【內飾清洗】微利天弘汽車美容裝飾",
"description": "微利天弘汽車美容裝飾 內飾清洗服務",
"notifyUrl": "http://app.cheguchina.com/wash/weixinpay/mobilenotify",
"payType": 30,
"ip": "218.28.20.138",
"prepay": {
"appId": "wx920fde9f97d60569",
"partnerId": "1220277201",
"prepayId": "920103900011129271ad0485b2fa00",
"package": "Sign=WXPay",
"timeStamp": "1452582979",
"nonce": "xl27JbHJSLcs52tv",
"sign": "1f3da1f83f60cbda0f715e6b0b9a0241b790d4"
}
}
}

在Appdeleagate.m中注冊商戶App,,並導入相關頭文件 

下面是主要的關鍵代碼:

#import "AppDelegate.h"
#import "WXApi.h"
#import "WXApiObject.h"


@interface AppDelegate ()<WXApiDelegate>

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    //1.AppID : 微信開發者平台注冊后給的一個應用標示
    //2.description : 沒什么用只是給開發者一種解釋的作用
    [WXApi registerApp:@"wx920fde9f97d60569" withDescription:@"demo 2.0"];
    
    return YES;
}


-(void)onResp:(BaseResp*)resp{
    
    if ([resp isKindOfClass:[PayResp class]]){
        PayResp *response=(PayResp*)resp;
        
        //通知中心傳值
        [[NSNotificationCenter defaultCenter] postNotificationName:@"weixinzhifu" object:response];
        
        
    
    }
}
View Code  Appdeleagate.m
#import "ViewController.h"
#import "WXApi.h"
#import "WXApiObject.h"
@interface ViewController ()<WXApiDelegate>

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}
- (IBAction)wxAtcion:(id)sender {
    
    //微信支付方法
    
    PayReq *request = [[PayReq alloc] init];
    
    
    //** 商家向財付通申請的商家id */
    request.partnerId = @"1220277201";
    //預支付訂單 (包含商品的信息 如價格 : 標題 , 描述 等信息)
    request.prepayId= @"8201038000160122a3971f85dc6f20d";
    //商家根據財付通文檔填寫的數據和簽名  類似一種標示
    request.package = @"Sign=WXPay";
    //隨機串
    request.nonceStr= @"5xv1tGmFhe1cq5IZ";
    //時間戳  (從1970年到現在的秒數)
    request.timeStamp = 1452582950;
    //商家根據微信開放平台文檔對數據做的簽名  (對數據的一種加密形勢)
    request.sign= @"0ac8963b331100acf5461e4d1ab726f7877912e";
    
    //調用微信支付的方法
    [WXApi sendReq:request];

    
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    
    //接受通知
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(weiXinPayBack:) name:@"weixinzhifu" object:nil];
}

//通知中心觸發的方法
- (void)weiXinPayBack:(NSNotification *)notification {
    
       PayResp *response=notification.object;
    
    switch(response.errCode){
        case WXSuccess:
            //服務器端查詢支付通知或查詢API返回的結果再提示成功
            NSLog(@"支付成功");
            break;
        default:
            NSLog(@"支付失敗,retcode=%d",response.errCode);
            break;
    }
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [[NSNotificationCenter debugDescription] removeObserver:self forKeyPath:@"weixinzhifu"];
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end
View Code  ViewController.m

這里已經能夠完成實現支付了,如果數據是真正從服務器獲得的數據就可以查看到支付結果了。


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com