比较简单,只做一个笔记,并于以后查询
1、将微信支付第三方库拖到项目中
2、添加微信支付需要的依赖库
3、环境配置
1)、https相关配置
2)、LSApplicationQueriesSchemes白名单设置
3)、URL Schemes配置,这边涂鸦掉的数值,和项目中注册微信支付时的appID一致
有两种方法设置,一种是在plist文件中
第二种是图形样式,info->URL Types
4)、bitcode配置
build setting -> bitcode
3、项目代码
控制器中的代码
代码中相关appID等参数写在头文件中,不方便写出来,换成自己项目中的配置参数就可以了
#import "ViewController.h"
//微信支付
#import "DataMD5.h"
#import "XMLDictionary.h"
#import "AFHTTPRequestOperationManager.h"
#import "WXApiObject.h"
#import "WXApi.h"
#import "getIPhoneIP.h"
#import "WXApi.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//微信支付-添加通知
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(weixinPaySuccess)
name:WeiXinPaySuccessNotification
object:nil];
}
- (void)viewDidUnload
{
//移除通知
[[NSNotificationCenter defaultCenter] removeObserver:self name:WeiXinPaySuccessNotification object:nil];
[super viewDidUnload];
}
//微信支付
- (IBAction)weixinPay:(id)sender {
//微信最后支付的价格=真实的价格*100
// NSString *payCount = [NSString stringWithFormat:@"%.0f",_rechargeAmount*100];
// [self weixinChooseActWithGlodNo:_rechargeOrderNumber payCount:payCount];
NSString *glodNo = [self generateTradeNO];//商品订单号
[self weixinChooseActWithGlodNo:glodNo payCount:@"1"];
}
#pragma make - 微信支付获取订单号、产品信息、签名、认证
#pragma mark 微信支付相关方法
- (void)weixinChooseActWithGlodNo:(NSString *)glodSn payCount:(NSString *)payCount {
NSString *appid,*mch_id,*nonce_str,*sign,*body,*out_trade_no,*total_fee,*spbill_create_ip,*notify_url,*trade_type,*partner;
//应用APPID
appid = WX_appID;
//微信支付商户号
mch_id = MCH_ID;
//产生随机字符串,这里最好使用和安卓端一致的生成逻辑
nonce_str =[self generateTradeNO];
body =@"项目名字+微信支付";
//随机产生订单号用于测试,正式使用请换成你从自己服务器获取的订单号
out_trade_no = glodSn;
//交易价格1表示0.01元,10表示0.1元
total_fee = payCount;
//获取本机IP地址,请再wifi环境下测试,否则获取的ip地址为error,正确格式应该是8.8.8.8
// spbill_create_ip =[getIPhoneIP getIPAddress];
//
spbill_create_ip =@"192.168.1.21";
//交易结果通知网站此处用于测试,随意填写,正式使用时填写正确网站
notify_url =@"www.cccuu.com";
trade_type =@"APP";
//商户密钥
partner = WX_partnerKey;
//获取sign签名
DataMD5 *data = [[DataMD5 alloc] initWithAppid:appid mch_id:mch_id nonce_str:nonce_str partner_id:partner body:body out_trade_no:out_trade_no total_fee:total_fee spbill_create_ip:spbill_create_ip notify_url:notify_url trade_type:trade_type];
sign = [data getSignForMD5];
//设置参数并转化成xml格式
NSMutableDictionary *dic = [NSMutableDictionary dictionary];
[dic setValue:appid forKey:@"appid"];//公众账号ID
[dic setValue:mch_id forKey:@"mch_id"];//商户号
[dic setValue:nonce_str forKey:@"nonce_str"];//随机字符串
[dic setValue:sign forKey:@"sign"];//签名
[dic setValue:body forKey:@"body"];//商品描述
[dic setValue:out_trade_no forKey:@"out_trade_no"];//订单号
[dic setValue:total_fee forKey:@"total_fee"];//金额
[dic setValue:spbill_create_ip forKey:@"spbill_create_ip"];//终端IP
[dic setValue:notify_url forKey:@"notify_url"];//通知地址
[dic setValue:trade_type forKey:@"trade_type"];//交易类型
// 转换成xml字符串
NSString *string = [dic XMLString];
[self http:string];
}
#pragma mark 拿到转换好的xml发送请求
- (void)http:(NSString *)xml {
// [MBProgressHUD showMessage:@"正在获取支付订单..."];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
//这里传入的xml字符串只是形似xml,但是不是正确是xml格式,需要使用af方法进行转义
manager.responseSerializer = [[AFHTTPResponseSerializer alloc] init];
[manager.requestSerializer setValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[manager.requestSerializer setValue:@"https://api.mch.weixin.qq.com/pay/unifiedorder" forHTTPHeaderField:@"SOAPAction"];
[manager.requestSerializer setQueryStringSerializationWithBlock:^NSString *(NSURLRequest *request, NSDictionary *parameters, NSError *__autoreleasing *error) {
return xml;
}];
//发起请求
[manager POST:@"https://api.mch.weixin.qq.com/pay/unifiedorder" parameters:xml success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSString *responseString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding] ;
// LXLog(@"responseString is %@",responseString);
//将微信返回的xml数据解析转义成字典
NSDictionary *dic = [NSDictionary dictionaryWithXMLString:responseString];
//判断返回的许可
if ([[dic objectForKey:@"result_code"] isEqualToString:@"SUCCESS"] &&[[dic objectForKey:@"return_code"] isEqualToString:@"SUCCESS"] ) {
//发起微信支付,设置参数
PayReq *request = [[PayReq alloc] init];
request.openID = [dic objectForKey:@"appid"];
request.partnerId = [dic objectForKey:@"mch_id"];
request.prepayId= [dic objectForKey:@"prepay_id"];
request.package = @"Sign=WXPay";
request.nonceStr= [dic objectForKey:@"nonce_str"];
//将当前事件转化成时间戳
NSDate *datenow = [NSDate date];
NSString *timeSp = [NSString stringWithFormat:@"%ld", (long)[datenow timeIntervalSince1970]];
UInt32 timeStamp =[timeSp intValue];
request.timeStamp= timeStamp;
// 签名加密
DataMD5 *md5 = [[DataMD5 alloc] init];
request.sign=[md5 createMD5SingForPay:request.openID partnerid:request.partnerId prepayid:request.prepayId package:request.package noncestr:request.nonceStr timestamp:request.timeStamp];
// 调用微信
[WXApi sendReq:request];
// [MBProgressHUD hideHUD];
}else{
NSLog(@"参数不正确,请检查参数");
// [MBProgressHUD hideHUD];
// [MBProgressHUD showError:@"支付错误!"];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"error is %@",error);
// [MBProgressHUD hideHUD];
// [MBProgressHUD showError:@"未完成支付"];
}];
}
#pragma mark 产生随机订单号
- (NSString *)generateTradeNO {
static int kNumber = 15;
NSString *sourceStr = @"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
NSMutableString *resultStr = [[NSMutableString alloc] init];
// srand(time(0)); // 此行代码有警告:
srand( (unsigned)time(0) );//上行改过之后
for (int i = 0; i < kNumber; i++) {
unsigned index = rand() % [sourceStr length];
NSString *oneStr = [sourceStr substringWithRange:NSMakeRange(index, 1)];
[resultStr appendString:oneStr];
}
return resultStr;
}
#pragma make 微信支付成功之后调用的
-(void)weixinPaySuccess
{
NSLog(@"微信支付成功,把对应的单子消除");
// 通知后台充值订单支付成功
}
@end
delegate中的代码
#import "AppDelegate.h"
#import "WXApi.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//微信支付注册
[WXApi registerApp:WX_appID];
return YES;
}
//微信支付-回调
//9.0之前调用的方法
-(BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
return [self weiXinPayOrZhiFuBaoForUrl:url];
}
//9.0之前调用的方法
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary*)options
{
return [self weiXinPayOrZhiFuBaoForUrl:url];
}
//9.0之后调用的方法
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation
{
return [self weiXinPayOrZhiFuBaoForUrl:url];
}
//微信支付回调方法处理
-(BOOL)weiXinPayOrZhiFuBaoForUrl:(NSURL *)url
{
if ([url.host isEqualToString:@"safepay"]) {//支付宝支付相关操作
}else if ([url.host isEqualToString:@"pay"]){//微信支付相关操作
return [WXApi handleOpenURL:url delegate:self];
}
return YES;
}
//WXApiDelegate
-(void)onResp:(BaseResp *)resp {
if ([resp isKindOfClass:[PayResp class]]) {
PayResp*response=(PayResp*)resp; // 微信终端返回给第三方的关于支付结果的结构体
switch (response.errCode) {
case WXSuccess:
{// 支付成功,向后台发送消息
NSLog(@"支付成功~~~");
[[NSNotificationCenter defaultCenter] postNotificationName:WeiXinPaySuccessNotification object:nil];
}
break;
case WXErrCodeCommon:
{ //签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常等
// [MBProgressHUD showError:@"支付失败"];
NSLog(@"支付失败~~~");
}
break;
case WXErrCodeUserCancel:
{ //用户点击取消并返回
NSLog(@"取消支付~~~");
// [MBProgressHUD showError:@"取消支付"];
}
break;
case WXErrCodeSentFail:
{ //发送失败
NSLog(@"发送失败~~~");
// [MBProgressHUD showError:@"发送失败"];
}
break;
case WXErrCodeUnsupport:
{ //微信不支持
NSLog(@"微信不支持~~~");
// [MBProgressHUD showError:@"微信不支持"];
}
break;
case WXErrCodeAuthDeny:
{ //授权失败
NSLog(@"授权失败~~~");
// [MBProgressHUD showError:@"授权失败"];
}
break;
default:
break;
}
}
}
- (void)applicationWillResignActive:(UIApplication *)application {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
@end
祝成功~~