亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

IOS客戶端如何接入微信支付的教程

2020-02-19 15:57:20
字體:
來源:轉載
供稿:網友

今天小編跟大家分享一下IOS客戶端如何接入微信支付的教程,感興趣的朋友跟小編一起來了解一下吧!

實際上,從代碼的角度,調起支付APP就是把一些關鍵的參數通過一定方式打包成為一個訂單,然后發送到支付平臺的服務器。所以,只要搞清楚了參數設置,搞清楚了每個支付平臺的SDK里面一些關鍵API的使用,基本上就可以很簡單的支持支付。

今天記錄一下客戶端里面,如何支持微信支付。首先。我們要仔細閱讀一下微信SDK的開發文檔,了解一下整個支付的大概流程。

然后根據提示,把相應的SDK下載下來,所謂的SDK,也就是一個鏈接庫和兩個頭文件,很簡單。

下載完畢,需要把SDK導入到工程里面,并且配置一下工程。因為開發者文檔已經有詳細描述,這里就不再復述。

從文檔看到,調起微信支付其實最核心的是一下這么一段

PayReq *request = [[[PayReq alloc] init] autorelease];request.partnerId = @10000100;request.prepayId= @1101000000140415649af9fc314aa427;request.package = @Sign=WXPay;request.nonceStr= @a462b76e7436e98e0ed6e13c64b4fd1c;request.timeStamp= @1397527777;request.sign= @582282D72DD2B03AD892830965F428CB16E7A256;[WXApi sendReq:request];

這里的范例是一段hardcode,真正使用的時候,參數都需要自行傳入。

為了搞清楚如何使用API,我們可以下載Sample代碼。不過,這個sample代碼應該是微信的實習生寫的,而且應該是一個對于C++比較熟悉,對于ObjectC比較陌生的實習生。。。代碼風格可以看出很多東西哈。。所以這個sample讀起來總覺得有點奇怪。當然,寫出這個demo也是需要不錯的水平,因為這個sample不僅僅是一些API的調用,還包括了一些算法的實現,MD5之類的。
看懂了sample之后,一般可以自己重構一下,成為自己APP里面的一個Manager類。

我是在2015 5 23下載的微信Sampel代碼,里面包括有:

ApiXml.h

ApiXml.m

WXUtil.h

WXUtil.m

payRequestHandler.h

payRequestHandler.m

如果比較看重命名規范的OC程序猿,就會覺得這個payRequestHandler類非常別扭,不符合camel命名規則,而且handler這個詞更偏向于c++風格。我就以這個類為原型,重構了一下,并改裝成一個傳參的方法,供自己的APP調用。APP里面賣商品,一般就是商品名字,價格兩個關鍵參數。所以這個重構的方法也只是提供這兩個參數的接口。
ApiXml.h && ApiXml.m && WXUtil.h && WXUtil.m不變

//// WechatPayManager.h//// Created by HuangCharlie on 5/24/15.////#import #import WXUtil.h#import ApiXml.h#import WXApi.h// 賬號帳戶資料// 更改商戶把相關參數后可測試#define APP_ID     @wx@@@@@@@@@@@@@@@@    //APPID#define APP_SECRET   @             //appsecret,看起來好像沒用//商戶號,填寫商戶對應參數#define MCH_ID     @@@@@@@@@@@//商戶API密鑰,填寫相應參數#define PARTNER_ID   @12345678901234567890123456789012//支付結果回調頁面#define NOTIFY_URL   @http://wxpay.weixin.qq.com/pub_v2/pay/notify.v2.php//獲取服務器端支付數據地址(商戶自定義)(在小吉這里,簽名算法直接放在APP端,故不需要自定義)#define SP_URL     @http://wxpay.weixin.qq.com/pub_v2/app/app_pay.php@interface WechatPayManager : NSObject{}//預支付網關url地址@property (nonatomic,strong) NSString* payUrl;//debug信息@property (nonatomic,strong) NSMutableString *debugInfo;@property (nonatomic,assign) NSInteger lastErrCode;//返回的錯誤碼//商戶關鍵信息@property (nonatomic,strong) NSString *appId,*mchId,*spKey;//初始化函數-(id)initWithAppID:(NSString*)appID       mchID:(NSString*)mchID       spKey:(NSString*)key;//獲取當前的debug信息-(NSString *) getDebugInfo;//獲取預支付訂單信息(核心是一個prepayID)- (NSMutableDictionary*)getPrepayWithOrderName:(NSString*)name                     price:(NSString*)price                    device:(NSString*)device;@end//// WechatPayManager.m//// Created by HuangCharlie on 5/24/15.////#import WechatPayManager.h@implementation WechatPayManager//初始化函數-(id)initWithAppID:(NSString*)appID mchID:(NSString*)mchID spKey:(NSString*)key{  self = [super init];  if(self)  {    //初始化私有參數,主要是一些和商戶有關的參數    self.payUrl  = @https://api.mch.weixin.qq.com/pay/unifiedorder;    if (self.debugInfo == nil){      self.debugInfo = [NSMutableString string];    }    [self.debugInfo setString:@];    self.appId = appID;//微信分配給商戶的appID    self.mchId = mchID;//    self.spKey = key;//商戶的密鑰  }  return self;}//獲取debug信息-(NSString*) getDebugInfo{  NSString *res = [NSString stringWithString:self.debugInfo];  [self.debugInfo setString:@];  return res;}//創建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=%@, self.spKey];  //得到MD5 sign簽名  NSString *md5Sign =[WXUtil md5:contentString];  //輸出Debug Info  [self.debugInfo appendFormat:@MD5簽名字符串:%@,contentString];  return md5Sign;}//獲取package帶參數的簽名包-(NSString *)genPackage:(NSMutableDictionary*)packageParams{  NSString *sign;  NSMutableString *reqPars=[NSMutableString string];  //生成簽名  sign    = [self createMd5Sign:packageParams];  //生成xml的package  NSArray *keys = [packageParams allKeys];  [reqPars appendString:@];  for (NSString *categoryId in keys) {    [reqPars appendFormat:@%@, categoryId, [packageParams objectForKey:categoryId],categoryId];  }  [reqPars appendFormat:@%@, sign];  return [NSString stringWithString:reqPars];}//提交預支付-(NSString *)sendPrepay:(NSMutableDictionary *)prePayParams{  NSString *prepayid = nil;  //獲取提交支付  NSString *send   = [self genPackage:prePayParams];  //輸出Debug Info  [self.debugInfo appendFormat:@API鏈接:%@, self.payUrl];  [self.debugInfo appendFormat:@發送的xml:%@, send];  //發送請求post xml數據  NSData *res = [WXUtil httpSend:self.payUrl method:@POST data:send];  //輸出Debug Info  [self.debugInfo appendFormat:@服務器返回:%@,[[NSString alloc] initWithData:res encoding:NSUTF8StringEncoding]];  XMLHelper *xml = [[XMLHelper alloc] autorelease];  //開始解析  [xml startParse:res];  NSMutableDictionary *resParams = [xml getDict];  //判斷返回  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]) {        //驗證業務處理狀態        prepayid  = [resParams objectForKey:@prepay_id];        return_code = 0;        [self.debugInfo appendFormat:@獲取預支付交易標示成功!];      }    }else{      self.lastErrCode = 1;      [self.debugInfo appendFormat:@gen_sign=%@  _sign=%@,sign,send_sign];      [self.debugInfo appendFormat:@服務器返回簽名驗證錯誤?。?!];    }  }else{    self.lastErrCode = 2;    [self.debugInfo appendFormat:@接口返回錯誤?。?!];  }  return prepayid;}- (NSMutableDictionary*)getPrepayWithOrderName:(NSString*)name                     price:(NSString*)price                    device:(NSString*)device{  //訂單標題,展示給用戶  NSString* orderName = name;  //訂單金額,單位(分)  NSString* orderPrice = price;//以分為單位的整數  //支付設備號或門店號  NSString* orderDevice = device;  //支付類型,固定為APP  NSString* orderType = @APP;  //發器支付的機器ip,暫時沒有發現其作用  NSString* orderIP = @196.168.1.1;  //隨機數串  srand( (unsigned)time(0) );  NSString *noncestr = [NSString stringWithFormat:@%d, rand()];  NSString *orderNO  = [NSString stringWithFormat:@%ld,time(0)];  //================================  //預付單參數訂單設置  //================================  NSMutableDictionary *packageParams = [NSMutableDictionary dictionary];  [packageParams setObject: self.appId forKey:@appid];    //開放平臺appid  [packageParams setObject: self.mchId forKey:@mch_id];   //商戶號  [packageParams setObject: orderDevice forKey:@device_info]; //支付設備號或門店號  [packageParams setObject: noncestr   forKey:@nonce_str];  //隨機串  [packageParams setObject: orderType  forKey:@trade_type]; //支付類型,固定為APP  [packageParams setObject: orderName  forKey:@body];    //訂單描述,展示給用戶  [packageParams setObject: NOTIFY_URL forKey:@notify_url]; //支付結果異步通知  [packageParams setObject: orderNO   forKey:@out_trade_no];//商戶訂單號  [packageParams setObject: orderIP   forKey:@spbill_create_ip];//發器支付的機器ip  [packageParams setObject: orderPrice  forKey:@total_fee];    //訂單金額,單位為分  //獲取prepayId(預支付交易會話標識)  NSString *prePayid;  prePayid = [self sendPrepay:packageParams];  if(prePayid == nil)  {    [self.debugInfo appendFormat:@獲取prepayid失??!];    return nil;  }  //獲取到prepayid后進行第二次簽名  NSString  *package, *time_stamp, *nonce_str;  //設置支付參數  time_t now;  time(&now);  time_stamp = [NSString stringWithFormat:@%ld, now];  nonce_str = [WXUtil md5:time_stamp];  //重新按提交格式組包,微信客戶端暫只支持package=Sign=WXPay格式,須考慮升級后支持攜帶package具體參數的情況  //package    = [NSString stringWithFormat:@Sign=%@,package];  package     = @Sign=WXPay;  //第二次簽名參數列表  NSMutableDictionary *signParams = [NSMutableDictionary dictionary];  [signParams setObject: self.appId forKey:@appid];  [signParams setObject: self.mchId forKey:@partnerid];  [signParams setObject: nonce_str  forKey:@noncestr];  [signParams setObject: package   forKey:@package];  [signParams setObject: time_stamp  forKey:@timestamp];  [signParams setObject: prePayid   forKey:@prepayid];  //生成簽名  NSString *sign = [self createMd5Sign:signParams];  //添加簽名  [signParams setObject: sign     forKey:@sign];  [self.debugInfo appendFormat:@第二步簽名成功,sign=%@,sign];  //返回參數列表  return signParams;}@end

然后,在需要調用微信支付的Controller里面,新建一個方法。在合適的地方調用。這個方法里面利用WechatPayManager這個類進行了初始化和參數封裝,然后把上述的核心代碼(PayReq那一段)

- (void)wxPayWithOrderName:(NSString*)name price:(NSString*)price{  //創建支付簽名對象 && 初始化支付簽名對象  WechatPayManager* wxpayManager = [[[WechatPayManager alloc]initWithAppID:APP_ID mchID:MCH_ID spKey:PARTNER_ID] autorelease];   //獲取到實際調起微信支付的參數后,在app端調起支付  //生成預支付訂單,實際上就是把關鍵參數進行第一次加密。  NSString* device = [[UserManager defaultManager]userId];  NSMutableDictionary *dict = [wxpayManager getPrepayWithOrderName:name                                price:price                             device:device];  if(dict == nil){    //錯誤提示    NSString *debug = [wxpayManager getDebugInfo];    return;  }  NSMutableString *stamp = [dict objectForKey:@timestamp];   //調起微信支付  PayReq* req       = [[[PayReq alloc] init]autorelease];  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]; //    BOOL flag = [WXApi sendReq:req];  BOOL flag = [WXApi safeSendReq:req];}

再者,支付完成了需要調用一個delegate,這個delegate方便個性化顯示支付結果。一般直接把這兩個delegate放在AppDelegate就好了。因為有一些其他內容也是需要在AppDelegate里面實現,省的分開找不到。

-(void) onResp:(BaseResp*)resp{   //啟動微信支付的response  NSString *strMsg = [NSString stringWithFormat:@errcode:%d, resp.errCode];  if([resp isKindOfClass:[PayResp class]]){    //支付返回結果,實際支付結果需要去微信服務器端查詢    switch (resp.errCode) {      case 0:        strMsg = @支付結果:成功!;        break;      case -1:        strMsg = @支付結果:失?。?        break;      case -2:        strMsg = @用戶已經退出支付!;        break;      default:        strMsg = [NSString stringWithFormat:@支付結果:失敗!retcode = %d, retstr = %@, resp.errCode,resp.errStr];        break;    }  }}

注意事項:

1)如果APP里面已經使用了ShareSDK,就有一些地方要注意。不要再重復導入微信的SDK,因為shareSDK里面的extend已經包括了微信的SDK。

2)微信本身是鼓勵客戶APP把簽名算法放到服務器上面,這樣信息就不容易被破解。但是如果客戶APP本身沒有服務器端,或者認為不需要放到服務器端,也可以直接把簽名(加密)的部分直接放在APP端。Sample代碼的注釋有點亂,多次提到服務器云云,但是其實可以不這么做。

3)微信的price單位是分。注意下即可。

4)暫時想不到,以后想到了再記錄。。

以上就是IOS客戶端如何接入微信支付的教程的全部內容介紹了,希望小編整理的相關知識和資料都對你們有所幫助,更多內容請繼續關注武林技術頻道網站!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲毛片在线观看| 最近日韩中文字幕中文| 欧美日韩人人澡狠狠躁视频| 国产精品第一页在线| 国产精品精品视频| 色哟哟网站入口亚洲精品| 日韩在线不卡视频| 欧美一级视频一区二区| 欧美成人在线影院| 久久精品成人动漫| 欧美视频在线观看免费| 国内揄拍国内精品| 欧美美女操人视频| 亚洲精品视频中文字幕| 久久久久久综合网天天| 高清日韩电视剧大全免费播放在线观看| 久热精品视频在线免费观看| 尤物精品国产第一福利三区| 欧美巨乳美女视频| 亚洲成人a级网| 欧美激情aaaa| 琪琪亚洲精品午夜在线| 欧美日韩中国免费专区在线看| 久久久久久久久综合| 欧美成人精品三级在线观看| 成人欧美在线视频| 国产精品高潮呻吟视频| 色悠久久久久综合先锋影音下载| 亚洲国产高清福利视频| 久久久精品免费| 国产精品91在线| 亚洲xxx视频| 欧美中文在线字幕| 综合网中文字幕| 日本成人精品在线| 97在线精品国自产拍中文| 欧美日韩国产中文字幕| 国产精品欧美激情| 日本精品免费一区二区三区| 亚洲国模精品私拍| 欧美刺激性大交免费视频| 欧美一性一乱一交一视频| 在线视频日本亚洲性| 久久久国产精品x99av| 亚洲第一免费播放区| 亚洲第一福利网| 中文字幕国产精品| 一道本无吗dⅴd在线播放一区| 伊人久久久久久久久久| 97久久超碰福利国产精品…| 一区二区三区国产在线观看| 久久中文字幕国产| 亚洲精品久久久久中文字幕二区| 大荫蒂欧美视频另类xxxx| 久久久久久久久综合| 国产日韩欧美自拍| 大量国产精品视频| 欧美一级大片视频| 日韩精品小视频| 精品国产欧美一区二区五十路| 亚洲free嫩bbb| 欧美一级黑人aaaaaaa做受| 国产精品大片wwwwww| 国产精品亚洲综合天堂夜夜| 亚洲精品短视频| 韩剧1988在线观看免费完整版| 岛国av一区二区| 亚洲精品久久久久| 日本中文字幕成人| 国产精品网站视频| 国产婷婷色综合av蜜臀av| 成人久久18免费网站图片| 欧美日韩成人网| 精品视频在线播放免| 国产精品国语对白| 91深夜福利视频| 国产婷婷成人久久av免费高清| 91免费电影网站| wwwwwwww亚洲| 国产精品av网站| 久久这里有精品视频| 亚洲精品suv精品一区二区| 一本久久综合亚洲鲁鲁| 狠狠色香婷婷久久亚洲精品| 国产在线精品成人一区二区三区| 色多多国产成人永久免费网站| 日韩精品中文字幕在线播放| 一本一道久久a久久精品逆3p| 亚洲精品永久免费精品| 亚洲一区二区三区四区在线播放| 欧美激情a∨在线视频播放| 91久久精品日日躁夜夜躁国产| 国内精品久久久久久久| 亚洲色图av在线| 欧美国产欧美亚洲国产日韩mv天天看完整| 欧美日韩另类字幕中文| 久久躁狠狠躁夜夜爽| 2019中文字幕全在线观看| 欧美激情中文网| 亚洲精品日韩av| 日韩成人在线电影网| 国产精品日韩欧美| 亚洲黄色片网站| 国产精品jvid在线观看蜜臀| 亚洲偷熟乱区亚洲香蕉av| 米奇精品一区二区三区在线观看| 尤物yw午夜国产精品视频明星| 91午夜在线播放| 九九视频这里只有精品| 久久久精品999| 亚洲第一福利网| 久久精品91久久久久久再现| 亚洲国产欧美一区二区丝袜黑人| 91精品国产高清| 中文字幕亚洲欧美日韩2019| 日韩av黄色在线观看| 亚洲女性裸体视频| 国产一区二区三区视频免费| 久久久久国产精品免费网站| 国产精品日韩在线播放| 欧美性猛交xxxx富婆弯腰| 91社影院在线观看| 精品久久久久国产| 日韩中文综合网| 色在人av网站天堂精品| www.午夜精品| 日韩av在线网页| 国产国产精品人在线视| 亚洲精品免费一区二区三区| 日韩欧美中文免费| 日韩精品视频免费专区在线播放| 日韩av中文字幕在线免费观看| 日本国产精品视频| 久久色免费在线视频| 国产精品电影在线观看| 国产香蕉97碰碰久久人人| 国产精品黄色影片导航在线观看| 日韩中文字幕不卡视频| 欧美有码在线观看| 欧美乱人伦中文字幕在线| 日韩激情视频在线播放| 久久久久久亚洲精品不卡| 日韩欧美成人精品| 欧美大片免费观看在线观看网站推荐| 色偷偷噜噜噜亚洲男人的天堂| 亚洲精品国偷自产在线99热| 亚洲网址你懂得| 日韩视频在线观看免费| 亚洲码在线观看| 国产精品久久久999| 欧美另类在线观看| 午夜精品久久久久久久久久久久| 亚洲自拍高清视频网站| 中文字幕日韩免费视频| 91在线高清免费观看| 亚洲综合在线中文字幕| 久久久电影免费观看完整版| 亚洲天堂第一页| 26uuu日韩精品一区二区| 亚洲人成在线电影| 九九热精品视频| 在线不卡国产精品| 亚洲精品国产精品久久清纯直播| 久久人人爽人人爽人人片av高清|