<code class = "hljs" objectivec= "" > //
// WechatPayManager.m
//
// Created by HuangCharlie on 5/24/15.
//
//
# import WechatPayManager.h
@implementation WechatPayManager
//初始化函數(shù)
-(id)initWithAppID:(NSString*)appID mchID:(NSString*)mchID spKey:(NSString*)key
{
self = [ super init];
if (self)
{
//初始化私有參數(shù),主要是一些和商戶有關(guān)的參數(shù)
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;
}
//創(chuàng)建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帶參數(shù)的簽名包
-(NSString *)genPackage:(NSMutableDictionary*)packageParams
{
NSString *sign;
NSMutableString *reqPars=[NSMutableString string];
//生成簽名
sign = [self createMd5Sign:packageParams];
//生成xml的package
NSArray *keys = [packageParams allKeys];
[reqPars appendString:@<xml>
];
for (NSString *categoryId in keys) {
[reqPars appendFormat:@<%@>%@<!--%@-->
, categoryId, [packageParams objectForKey:categoryId],categoryId];
}
[reqPars appendFormat:@<sign>%@</sign>
</xml>, sign];
return [NSString stringWithString:reqPars];
}
//提交預(yù)支付
-(NSString *)sendPrepay:(NSMutableDictionary *)prePayParams
{
NSString *prepayid = nil;
//獲取提交支付
NSString *send = [self genPackage:prePayParams];
//輸出Debug Info
[self.debugInfo appendFormat: @API 鏈接:%@
, self.payUrl];
[self.debugInfo appendFormat:@發(fā)送的xml:%@
, send];
//發(fā)送請求post xml數(shù)據(jù)
NSData *res = [WXUtil httpSend:self.payUrl method: @POST data:send];
//輸出Debug Info
[self.debugInfo appendFormat:@服務(wù)器返回:
%@
,[[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 ] )
{
//生成返回數(shù)據(jù)的簽名
NSString *sign = [self createMd5Sign:resParams ];
NSString *send_sign =[resParams objectForKey: @sign ] ;
//驗證簽名正確性
if ( [sign isEqualToString:send_sign]){
if ( [result_code isEqualToString: @SUCCESS ]) {
//驗證業(yè)務(wù)處理狀態(tài)
prepayid = [resParams objectForKey: @prepay_id ];
return_code = 0 ;
[self.debugInfo appendFormat:@獲取預(yù)支付交易標(biāo)示成功,!
];
}
} else {
self.lastErrCode = 1 ;
[self.debugInfo appendFormat: @gen_sign =%@
_sign=%@
,sign,send_sign];
[self.debugInfo appendFormat:@服務(wù)器返回簽名驗證錯誤!?。?/code>
];
}
} else {
self.lastErrCode = 2 ;
[self.debugInfo appendFormat:@接口返回錯誤?。,。?/code>
];
}
return prepayid;
}
- (NSMutableDictionary*)getPrepayWithOrderName:(NSString*)name
price:(NSString*)price
device:(NSString*)device
{
//訂單標(biāo)題,,展示給用戶
NSString* orderName = name;
//訂單金額,單位(分)
NSString* orderPrice = price; //以分為單位的整數(shù)
//支付設(shè)備號或門店號
NSString* orderDevice = device;
//支付類型,,固定為APP
NSString* orderType = @APP ;
//發(fā)器支付的機(jī)器ip,暫時沒有發(fā)現(xiàn)其作用
NSString* orderIP = @196 .168. 1.1 ;
//隨機(jī)數(shù)串
srand( (unsigned)time( 0 ) );
NSString *noncestr = [NSString stringWithFormat:@%d, rand()];
NSString *orderNO = [NSString stringWithFormat:@%ld,time( 0 )];
//================================
//預(yù)付單參數(shù)訂單設(shè)置
//================================
NSMutableDictionary *packageParams = [NSMutableDictionary dictionary];
[packageParams setObject: self.appId forKey: @appid ]; //開放平臺appid
[packageParams setObject: self.mchId forKey: @mch_id ]; //商戶號
[packageParams setObject: orderDevice forKey: @device_info ]; //支付設(shè)備號或門店號
[packageParams setObject: noncestr forKey: @nonce_str ]; //隨機(jī)串
[packageParams setObject: orderType forKey: @trade_type ]; //支付類型,固定為APP
[packageParams setObject: orderName forKey: @body ]; //訂單描述,,展示給用戶
[packageParams setObject: NOTIFY_URL forKey: @notify_url ]; //支付結(jié)果異步通知
[packageParams setObject: orderNO forKey: @out_trade_no ]; //商戶訂單號
[packageParams setObject: orderIP forKey: @spbill_create_ip ]; //發(fā)器支付的機(jī)器ip
[packageParams setObject: orderPrice forKey: @total_fee ]; //訂單金額,,單位為分
//獲取prepayId(預(yù)支付交易會話標(biāo)識)
NSString *prePayid;
prePayid = [self sendPrepay:packageParams];
if (prePayid == nil)
{
[self.debugInfo appendFormat:@獲取prepayid失敗,!
];
return nil;
}
//獲取到prepayid后進(jìn)行第二次簽名
NSString * package , *time_stamp, *nonce_str;
//設(shè)置支付參數(shù)
time_t now;
time(&now);
time_stamp = [NSString stringWithFormat:@%ld, now];
nonce_str = [WXUtil md5:time_stamp];
//重新按提交格式組包,,微信客戶端暫只支持package=Sign=WXPay格式,須考慮升級后支持?jǐn)y帶package具體參數(shù)的情況
//package = [NSString stringWithFormat:@Sign=%@,package];
package = @Sign =WXPay;
//第二次簽名參數(shù)列表
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];
//返回參數(shù)列表
return signParams;
}
@end </code>
|