最近因为公司项目需求,需要做iOS的位置支付,所谓初生牛犊不怕虎,博主直接二话不说就像二愣子一样的直接上手做了,虽然之前知道iOS使用OC(object-c)做的开发,到了真正接触了才发现,o my God ,OC的语言特性和c,c++,C#都不一样,虽然都是c语言一类的,博主直接懵逼了,还好在百度加网上各种demo各种教程的找,终于解决了iOS的支付问题,
其实博主发现,网上引用的微信的SDK大都是2015年的,不是微信比较新的SDK,加上博主的工程里也集成了shareSDK的微信登录和分享,所以发现需要用最新的SDK才可以,没办法,所以又是一天的搞事,最后用的是微信目前最新的SDK成功接入
最后博主会上传自己的事例代码,都会一步一步的写清楚,因为知道不懂OC,直接看OC 代码是多么懵逼,我相信小白也能看懂
由于今天的时间问题和暂时没有截图,所以明天会把剩下的不分补上去,这算是个前传吧
提示:所有的加密和通讯都在客户端进行
今天开始补上之前没有更新的unity接入iOS支付
把标注的红色文件拖到unity的assets/Plugins/iOS目录下,如果没有动手创建。然后拖一个button,新建一个脚本,开始写代码
首先引用命名空间System.Runtime.InteropServices;
[DllImport("__Internal")]
private static extern void wxpaytest(string orderN, string orderP);
orderN和orderP是在unity传给iOS的参数,orderN是订单名称,orderP是订单金额,分为单位
这是在告诉unity,会有一个函数是在外部实现的,unity用C#,C#可以调用C语言,
切记切记,__Internal是两个下划线
在unity如下图配置
写一个函数调用wxpaytest函数
然后就可以直接bulid导出iOS,在Xcode打开后,
在导出的Xcode文件中找到Prefix.pch头文件,在class目录,把下面的文字复制进去,保存
*复制的文字*******
//微信开放平台中创建的应用的appid
#define APP_id @”“
//商家id
#define MCH_id @”1”
//微信商户中心里面设置的32位的字符串
#define PARTNER_id @”“
#define nocify_url @”www.baidu.com”
#define WEIXINPAYSUCCESSED @”WeiXinPaysucceed”
*复制的文字*******
然后再UnityAppController.mm文件中,填写下面的代码
粘在下一行代码。如果没有这一句,支付完成后程序不会执行回调,下面的代码复制到UnityAppController.mm
void wxpaytest(char* orderN,char* orderP)
{
payRequsestHandler *handle = [[payRequsestHandler alloc]init];
if ( [handle init:APP_id mch_id:MCH_id]) {
NSLog(@"初始化成功");
}
//设置商户密钥
[handle setKey:PARTNER_id];
//提交预支付,获得prepape_id
NSString *order_name = [[NSString alloc] initWithUTF8String:orderN]; //订单标题
NSString *order_price = [[NSString alloc] initWithUTF8String:orderP];//测试价格 分为单位
NSString *nocify_URL = nocify_url; //回调借口
NSString *noncestr = [NSString stringWithFormat:@"%d", rand()]; //随机串
NSString *orderno = [NSString stringWithFormat:@"%ld",time(0)];
NSMutableDictionary *params = [@{@"appid":APP_id,
@"mch_id":MCH_id,
@"device_info":[[[UIDevice currentDevice] identifierForVendor] UUIDString],
@"nonce_str":noncestr,
@"trade_type":@"APP",
@"body":order_name,
@"notify_url":nocify_URL,
@"out_trade_no":orderno,//商户订单号:这个必须用后台的订单号
@"spbill_create_ip":@"8.8.8.8",
@"total_fee":order_price}mutableCopy];
//提交预支付两次签名得到预支付订单的id(每次的请求得到的预支付订单id都不同)
NSString *prepate_id = [handle sendPrepay:params];
//提交预订单成功
if (prepate_id != nil) {
PayReq *request = [[PayReq alloc]init];
//商家id
request.partnerId = MCH_id;
//订单id
request.prepayId = prepate_id;
//扩展字段(官方文档:暂时填写固定值)
request.package = @"Sign=WXPay";
//随机字符串
request.nonceStr = noncestr;
//时间戳
request.timeStamp = (UInt32)[[NSDate date] timeIntervalSince1970];
//sign参数(很经常出现的问题:就是调起支付到微信那边只出现一个确定按钮,单击确认按钮直接返回到app,出现这个问题100%是sign参数的问题)
/*
参数依次是: appid_key、partnerid_key、prepayid_key、固定值Sign=WXPay、预支付的随机数(跟上面得到预支付订单的随机数要一致)、支付时间(秒)
*/
//request.sign = [selfClass createMD5SingForPay:APP_id partnerid:MCH_id prepayid:prepate_id package:@"Sign=WXPay" noncestr:noncestr timestamp:(UInt32)[[NSDate date] timeIntervalSince1970]];
NSMutableDictionary *signParams = [NSMutableDictionary dictionary];
[signParams setObject:APP_id forKey:@"appid"];
[signParams setObject:noncestr forKey:@"noncestr"];
[signParams setObject:@"Sign=WXPay" forKey:@"package"];
[signParams setObject:MCH_id forKey:@"partnerid"];
[signParams setObject:prepate_id forKey:@"prepayid"];
[signParams setObject:[NSString stringWithFormat:@"%u",(unsigned int)(UInt32)[[NSDate date] timeIntervalSince1970]] forKey:@"timestamp"];
NSMutableString *contentString =[NSMutableString string];
NSArray *keys = [signParams allKeys];
//按字母顺序排序
NSArray *sortedArray = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [obj1 compare:obj2 options:NSNumericSearch];
}];
//拼接字符串
for (NSString *categoryId in sortedArray) {
if ( ![[signParams objectForKey:categoryId] isEqualToString:@""]
&& ![[signParams objectForKey:categoryId] isEqualToString:@"sign"]
&& ![[signParams objectForKey:categoryId] isEqualToString:@"key"]
)
{
[contentString appendFormat:@"%@=%@&", categoryId, [signParams objectForKey:categoryId]];
}
}
//添加商户密钥key字段
[contentString appendFormat:@"key=%@",PARTNER_id];
// NSString *resul = [self md5:contentString];
const char *cStr = [contentString UTF8String];
unsigned char result[16]= "0123456789abcdef";
CC_MD5(cStr, (CC_LONG)strlen(cStr), result);
//这里的x是小写则产生的md5也是小写,x是大写则md5是大写,这里只能用大写,微信的大小写验证很逗
NSString *resul = [NSString stringWithFormat:
@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
result[0], result[1], result[2], result[3],
result[4], result[5], result[6], result[7],
result[8], result[9], result[10], result[11],
result[12], result[13], result[14], result[15]
];
request.sign = resul;
//带起微信支付
if ([WXApi sendReq:request]) {
}else{
//未安装微信客户端
[[[UIAlertView alloc]initWithTitle:@"测试demo" message:@"您还未安装微信客户端,请前往Appstore下载或者选择其他支付方式!" delegate:nil cancelButtonTitle:@"知道了" otherButtonTitles:nil, nil]show];
}
//接受成功的通知
[[NSNotificationCenter defaultCenter]addObserver:nil selector:@selector(succeed) name:WEIXINPAYSUCCESSED object:nil];
NSLog(@"wanc");
}
}
把之前拖进unity的文件AppDelegate.m复制下面的代码到UnityAppController.mm
iOS回调unity
UnitySendMessage(<#const char *obj#>, <#const char *method#>, <#const char *msg#>)
第一个参数是物体名称,也就是挂载回调脚本的物体,第二个参数时会掉方法的名称,第三个参数时返回给回调函数的参数,三个参数必须是字符类型,不能是其他类型,回调函数写在onResp的支付回调函数中
微信返回的参数0是成功,-1是失败,-2是取消
接下来,在UnityAppController.mm找到didFinishLaunchingWithOptions函数,写注册微信支付,[WXApi registerApp:APP_id withDescription:@”demo”];
还需要引用支持的库文件libc.tbd,libz.tbd,libsqlite3.tbd,coretelephony.framework,security.framework。然后
在info文件里如下图配置,数组类型,不要填错了
这个时候就可以连接设备,编译文件了,