ios 支付宝:移动支付2

ios 支付宝:移动支付1

http://blog.csdn.net/dynastyting/article/details/51304293

ios 支付宝:移动支付2

http://blog.csdn.net/dynastyting/article/details/51312271








ios中

        [[AlipaySDKdefaultService]payOrder:orderStringfromScheme:appSchemecallback:^(NSDictionary *resultDic) {

            //callback处理支付结果为同步通知

            NSLog(@"reslut = %@",resultDic);

        }];


resultDic为形如以下字典

    memo = "";

    result = "partner=\"2088221664440135\"&seller_id=\"qmmodify@126.com\"&out_trade_no=\"Q34FAVRNJFTF12Z\"&subject=\"x5\U6fc0\U5149,x5\U706b\U82b1\"&body=\"\U6b64\U6b21X5\U7684\U6539\U6b3e\U66f4\U91cd\U8981\U7684\U4e00\U70b9\U5c31\U662f\U589e\U5f3a\U5e74\U8f7b\U6c14\U606f\Uff0c\U5c3e\U90e8\U867d\U7136\U4fdd\U7559\U4e86\U4e0a\U4e00\U4ee3\U7a33\U91cd\U7684\U6c14\U606f\Uff0c\U4f46\U6574\U4f53\U7684\U7ec6\U8282\U6539\U53d8\U8ba9\U5176\U770b\U8d77\U6765\U66f4\U65f6\U5c1a\Uff0c\U66f4\U52a0\U8fd0\U52a8\Uff0c\U66f4\U5bb9\U6613\U88ab\U5e74\U8f7b\U7fa4\U4f53\U63a5\U53d7\U3002\U5176\U4e2d\U5c3e\U706f\U4f9d\U7136\U662f\U706f\U5e26\U5f0f\U8bbe\U8ba1\Uff0c\U5176\U4e2d\U8be0\U91ca\U7684\U610f\U4e49\U662f\U70e7\U7ea2\U7684\U6392\U6c14\U7ba1\Uff0c\U4ee3\U8868\U5b9d\U9a6c\U8fd0\U52a8\U7684\U7cbe\U9ad3,i\U4fc4\U56fd\U548c\U70ed\U72d7\U7ea2\U65e5\U5149\U5982\U679chi\U97e9\U56fd\U641e\U540e\U641e\U5bc4\U6b27\U4e8634\U5c3143\U6b27\U51a0\U4ef6  3\U5339\U914d \U5bf94 \U5c31\U80a9\U8d1f 34i\U7ed9\U5bb6 \Ufe3f(\Uffe3\Ufe36\Uffe3)\Ufe3f\U54e6(\U2299o\U2299)\U54e6\U4e2a\U8fea\U8fea\U4f1a43 \U653e   i34jfi43j\U770b\U4e86\U70ed\U54e6\Ufe3f(\Uffe3\Ufe36\Uffe3)\Ufe3f  34\U9ad8\U7c92\U770b\U540e\U611fi4 3\U5de5i\U4e2a43\U54e6\U7684 \U5bf94\U5076\U8bb0\U5f9743\U54e6\Ufe3f(\Uffe3\Ufe36\Uffe3)\Ufe3f\U54e64\U54e6\U641e\U5594<(\Uffe3\Ufe36\Uffe3)\U2197[GO!] <(\Uffe3\Ufe36\Uffe3)\U2197[GO!]\U591f \U768434 \U56624 \U76ae\U80a43 \Ufe3f(\Uffe3\Ufe36\Uffe3)\Ufe3f\U5e73\U641e\U641e\U5e73\U5149\U76d8\U72d7\U5c41 \U62cd\U6539 \U8bc4\U4f30i3\U8bc4\U4f30IP\U7ed9 3\U7ed9 \U516c\U5e73 3\U7ed93 \U3002;\U6b64\U6b21X5\U7684\U6539\U6b3e\U66f4\U91cd\U8981\U7684\U4e00\U70b9\U5c31\U662f\U589e\U5f3a\U5e74\U8f7b\U6c14\U606f\Uff0c\U5c3e\U90e8\U867d\U7136\U4fdd\U7559\U4e86\U4e0a\U4e00\U4ee3\U7a33\U91cd\U7684\U6c14\U606f\Uff0c\U4f46\U6574\U4f53\U7684\U7ec6\U8282\U6539\U53d8\U8ba9\U5176\U770b\U8d77\U6765\U66f4\U65f6\U5c1a\Uff0c\U66f4\U52a0\U8fd0\U52a8\Uff0c\U66f4\U5bb9\U6613\U88ab\U5e74\U8f7b\U7fa4\U4f53\U63a5\U53d7\U3002\U5176\U4e2d\U5c3e\U706f\U4f9d\U7136\U662f\U706f\U5e26\U5f0f\U8bbe\U8ba1\Uff0c\U5176\U4e2d\U8be0\U91ca\U7684\U610f\U4e49\U662f\U70e7\U7ea2\U7684\U6392\U6c14\U7ba1\Uff0c\U4ee3\U8868\U5b9d\U9a6c\U8fd0\U52a8\U7684\U7cbe\U9ad3\U3002\"&total_fee=\"0.01\"&notify_url=\"http://192.168.1.116:8080/refitcar/notify_url.jsp\"&service=\"mobile.securitypay.pay\"&payment_type=\"1\"&_input_charset=\"utf-8\"&it_b_pay=\"30m\"&success=\"true\"&sign_type=\"RSA\"&sign=\"aH560tPSQDUcB1kpXY/VNNboYG1lM8bwNuC0Td0/fY6tA09Yu+islEC97nzjB+DWDMTDn8STl+Z1K1BZY98CqR67q/UY7cm675LffieehTkU6F+rl5T7c+TBXQMZUtQQT+zFNJqRO8fdAyNIhuEfPCDxuTTUWp2eg9vj5bHVN48=\"";

    resultStatus = 9000;






orderString 为以下的请求参数:

partner="2088101568358171"&seller_id="xxx@alipay.com"&out_trade_no="0819145412-6177"&subject="测试"&body="测试测试"&total_fee="0.01"&notify_url="http://notify.msp.hk/notify.htm"&service="mobile.securitypay.pay"&payment_type="1"&_input_charset="utf-8"&it_b_pay="30m"&sign="lBBK%2F0w5LOajrMrji7DUgEqNjIhQbidR13GovA5r3TgIbNqv231yC1NksLdw%2Ba3JnfHXoXuet6XNNHtn7VE%2BeCoRO1O%2BR1KugLrQEZMtG5jmJIe2pbjm%2F3kb%2FuGkpG%2BwYQYI51%2BhA3YBbvZHVQBYveBqK%2Bh8mUyb7GM1HxWs9k4%3D"&sign_type=“RSA"


sign在服务端签名时,若服务端为java版 那么服务端要用PKCS8格式私钥来签名,而不是RSA私钥来签名否则签名字符串为nil

服务端签名时支付宝提供的工具类 还需要urlEncodedString 这是支付宝的一大坑 

因为iOS端signString:方法中会urlEncodedString

    //获取私钥并将商户信息签名,外部商户可以根据情况存放私钥和签名,只需要遵循RSA签名规范,并将签名字符串base64编码和UrlEncode

    id<DataSigner> signer =CreateRSADataSigner(ALIPAY_PRIVATE_KEY);

    NSString *signedString = [signersignString:orderSpec];


signString方法:

//该签名方法仅供参考,外部商户可用自己方法替换

- (NSString *)signString:(NSString *)string {

//Document文件夹下创建私钥文件

NSString * signedString =nil;

NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES)objectAtIndex:0];

NSString *path = [documentPathstringByAppendingPathComponent:@"AlixPay-RSAPrivateKey"];

//

// 把密钥写入文件

//

NSString *formatKey = [selfformatPrivateKey:_privateKey];

[formatKey writeToFile:pathatomically:YESencoding:NSUTF8StringEncodingerror:nil];

constchar *message = [stringcStringUsingEncoding:NSUTF8StringEncoding];

    NSLog(@"%s",message);

    int messageLength = (int)strlen(message);

    unsignedchar *sig = (unsignedchar *)malloc(256);

unsignedint sig_len;

    int ret =rsa_sign_with_private_key_pem((char *)message, messageLength, sig, &sig_len, (char *)[pathUTF8String]);

//签名成功,需要给签名字符串base64编码和UrlEncode,该两个方法也可以根据情况替换为自己函数

    if (ret ==1) {

        NSString *base64String =base64StringFromData([NSDatadataWithBytes:siglength:sig_len]);

//NSData * UTF8Data = [base64String dataUsingEncoding:NSUTF8StringEncoding];

        NSLog(@"%@",base64String);

signedString = [selfurlEncodedString:base64String];//一定要注意这里有UrlEncode

    }

free(sig);

    return signedString;

}


注意:如果订单号固定 也就是每个字符串固定那么 signedString一定是一样的  而支付宝服务端的签名只是做到了 base64String这一步 ,而没有走urlEncodedString这一步,需要手动添加代码实现UrlEncode处理

同步通知客户端返回码

返回码

含义

9000

订单支付成功

8000

正在处理中

4000

订单支付失败

6001

用户中途取消

6002

网络连接出错


异步通知交易状态

枚举名称

枚举说明

WAIT_BUYER_PAY

交易创建,等待买家付款。

TRADE_CLOSED

在指定时间段内未支付时关闭的交易;

在交易完成全额退款成功时关闭的交易。

TRADE_SUCCESS

交易成功,且可对该交易做操作,如:多级分润、退款等。

TRADE_FINISHED

交易成功且结束,即不可再做任何操作。


服务器异步通知参数说明

https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.oUnx1f&treeId=59&articleId=103666&docType=1

以下为不可空的字符串

notify_time

通知时间

Date

通知的发送时间。格式为yyyy-MM-dd HH:mm:ss。

不可空

2013-08-22 14:45:24

notify_type

通知类型

String

通知的类型。

不可空

trade_status_sync

notify_id

通知校验ID

String

通知校验ID。

不可空

64ce1b6ab92d00ede0ee56ade98fdf2f4c

sign_type

签名方式

String

固定取值为RSA。

不可空

RSA

sign

签名

String

请参见签名机制

不可空

lBBK%2F0w5LOajrMrji7DUgEqNjIhQbidR13GovA5r3TgIbNqv231yC1NksLdw%2Ba3JnfHXoXuet6XNNHtn7VE%2BeCoRO1O%2BR1KugLrQEZMtG5jmJI


trade_no

支付宝交易号

String(64)

该交易在支付宝系统中的交易流水号。最短16位,最长64位。

不可空

2013082244524842

trade_status

交易状态

String

交易状态,取值范围请参见“交易状态”。

不可空

TRADE_SUCCESS

seller_id

卖家支付宝用户号

String(30)

卖家支付宝账号对应的支付宝唯一用户号。以2088开头的纯16位数字。

不可空

2088501624816263

seller_email

卖家支付宝账号

String(100)

卖家支付宝账号,可以是email和手机号码。

不可空

xxx@alipay.com

buyer_id

买家支付宝用户号

String(30)

买家支付宝账号对应的支付宝唯一用户号。以2088开头的纯16位数字。

不可空

2088602315385429

buyer_email

买家支付宝账号

String(100)

买家支付宝账号,可以是Email或手机号码。

不可空

dlwdgl@gmail.com

total_fee

交易金额

Number

该笔订单的总金额。请求时对应的参数,原样通知回来。

不可空

1.00


为了demo方便请求参数拼装和加签都放在了客户端, 应该都放服务端 


各个参数说明

partner //签约的支付宝账号对应的支付宝唯一用户号。以2088开头的16位纯数字组成。

seller_id  //卖家支付宝账号(邮箱或手机号码格式)或其对应的支付宝唯一用户号(以2088开头的纯16位数字)

out_trade_no  //商户网站唯一订单号:支付宝合作商户网站唯一订单号  订单号可以采用自己的订单号生成规则  这个订单号并不是支付的流水号

subject 商品名称累加中间用逗号隔开,如果一个商品买了几份只显示这一个名字  比如 商品A,商品A,商品B    应该写成 商品A,商品B//商品名称:商品的标题/交易标题/订单标题/订单关键字等。该参数最长为128个汉字****


body   商品描述累加中间用分号隔开 //String(512) 该参数最长512个汉字  商品详情:对一笔交易的具体描述信息。如果是多种商品,请将商品描述字符串累加传给body*******



total_fee   %.2f保留2位小数 //总金额:该笔订单的资金总额,单位为RMB-Yuan。取值范围为[0.01100000000.00],精确到小数点后两位

notify_url  //服务器异步通知页面路径:支付宝服务器主动通知商户网站里指定的页面http路径

service   //接口名称,固定值。 移动支付为 mobile.securitypay.pay

payment_type  //支付类型。默认值为:1(商品购买)

_input_charset  //商户网站使用的编码格式,固定为utf-8


it_b_pay  //未付款交易的超时时间 //30m  代表30分钟,可空


sign  服务端签名

sign_type  "RSA"

















-(void)alipayOrder{

    

    Order *order = [[Orderalloc]init];

    order.partner =ALIPAY_PID;

    order.seller =ALIPAY_SELLER;

    order.tradeNO =@"20160503203040";//[order generateTradeNO];

    

    NSMutableString* productName = [NSMutableStringnew];

    NSMutableString* productDes = [NSMutableStringnew];

    for (NSDictionary *datainself.dataSource) {

        NSDictionary *item = data[SHOPPING_CAR_PRODUCT_INFO];

        

        NSString *productNameStr = [NSStringstringWithFormat:@"%@", item[SHOPPING_CAR_PRODUCT_INFO_NAME]];

        productName = [NSMutableStringstringWithFormat:@"%@,%@", productName, productNameStr];

        

        NSString *productDesStr = [NSStringstringWithFormat:@"%@", item[SHOPPING_CAR_PRODUCT_INFO_DES]];

        productDes = [NSMutableStringstringWithFormat:@"%@;%@", productDes, productDesStr];

    }

    

    NSString * subjects = [NSStringstringWithString:productName];

    if (productName.length >128) {

         //substringToIndex表示从第一个字符串开始截取,到指定长度位置,但是不包括该指定位置位置字符串

        subjects = [subjects  substringToIndex:128];

        //substringFromIndex //表示从指定位置开始截取字符串到最后,所截取位置包含该指定位置

    }

    subjects = [subjects  substringFromIndex:1];//去掉首字符逗号

    

    NSString * bodys = [NSStringstringWithString:productDes];

    if (productDes.length >512) {

        bodys = [bodys  substringToIndex:512];

    }

    bodys = [bodys  substringFromIndex:1];//去掉首字符分号

    

    //商品的标题/交易标题/订单标题/订单关键字等。该参数最长为128个汉字。

    order.productName = subjects;

    //String(512):对一笔交易的具体描述信息。如果是多种商品,请将商品描述字符串累加传给body

    order.productDescription = bodys;

    

    //该笔订单的资金总额,单位为RMB-Yuan。取值范围为[0.01100000000.00],精确到小数点后两位。

    order.amount =@"0.01";//[NSString stringWithFormat:@"%.2ld",(long)[self computeTotalPrice]];//保留2位小数

    

    order.notifyURL =ALIPAY_NOTIFY_URL;

    order.service =@"mobile.securitypay.pay";

    order.paymentType =@"1";

    order.inputCharset =@"utf-8";

    order.itBPay =@"30m";

    //应用注册scheme,Info.plist定义URL types

    NSString *appScheme =APPSCHEME;

    //将商品信息拼接成字符串

    NSString *orderSpec = [orderdescription];

    NSLog(@"orderSpec = %@",orderSpec);

    

    

    //获取私钥并将商户信息签名,外部商户可以根据情况存放私钥和签名,只需要遵循RSA签名规范,并将签名字符串base64编码和UrlEncode

    id<DataSigner> signer =CreateRSADataSigner(ALIPAY_PRIVATE_KEY);

    NSString *signedString = [signersignString:orderSpec];

//    signedString = [self urlEncodedString:@"lTP/kWT47jcCl8nFRynsHqvxoBBQ+RDAW+L7Zc0cIWEJdGjFrmrQsP5aSEiNtDTSLQa6/uVC3XaSgkFI+eN0xqmyFwAjBWFUnpx4a6HgSLLL+3X/1czh7dg4/Vq7Q2uRfYzPm5iZscP+QNqTc62JxRKKs2AIDylzZS6z5bNjXF8="] ;

//     NSLog(@"signedString = %@",signedString);

    //将签名成功字符串格式化为订单字符串,请严格按照该格式

    NSString *orderString =nil;

    if (signedString !=nil) {

        orderString = [NSStringstringWithFormat:@"%@&sign=\"%@\"&sign_type=\"%@\"",

                       orderSpec, signedString, @"RSA"];

        NSLog(@"orderString = %@",orderString);

        [[AlipaySDKdefaultService]payOrder:orderStringfromScheme:appSchemecallback:^(NSDictionary *resultDic) {

            //callback处理支付结果】

            NSLog(@"reslut = %@",resultDic);

        }];

    }

}


代码中:

ALIPAY_PID

ALIPAY_SELLER

ALIPAY_NOTIFY_URL

APPSCHEME

ALIPAY_PRIVATE_KEY

为我自己的字符串宏替换为你们自己对应的字符串





同步通知参数说明

支付宝对商户的请求数据处理完成后,会将处理的结果数据直接通知给商户。这些处理结果数据就是同步通知参数。

同步返回的数据,对于商户在服务端没有收到异步通知的时候,可以依赖服务端对同步返回的结果来进行判断是否支付成功。同步返回的结果中,sign字段描述了请求的原始数据和服务端支付的状态一起拼接的签名信息。验证这个过程包括两个部分:1、原始数据是否跟商户请求支付的原始数据一致(必须验证这个);2、验证这个签名是否能通过。上述1、2通过后,在sign字段中success=true才是可信的。【特别注意,同步结果校验的逻辑,必须放在服务端处理,切记不要放在客户端】【强烈建议商户直接依赖服务端的异步通知,忽略同步返回】

说明:

这里的规则仅限于接入sdk支付模式,对于纯粹的WAP浏览器接入的模式不适用,也就是只针对签约mobile.securitypay.pay这个服务的业务适用,浏览器模式,建议走异步通知的方式。


代码示例运行逻辑

注意:

由于在跳转支付宝客户端支付的过程中,商户app在后台很可能被系统kill了,所以pay接口的callback就会失效,请商户对standbyCallback返回的回调结果进行处理;

同步返回数据时,建议通过服务端的验签功能代码做验签处理,之后再对返回的数据做业务逻辑处理;

须以服务器异步通知的结果数据为准,并对其做业务逻辑处理;

SDK付款有两种模式:如果外部存在支付宝钱包,则直接跳转到支付宝钱包付款;不存在的场景下,在SDK内部进行H5支付。测试同学需要关注这两类测试场景。



以下信息请忽略:

此类接口网关一般为mapi(https://mapi.alipay.com/gateway.do 

在开放平台创建的应用,每个应用都有自己的应用密钥(RSA),在接口网关为openapi(https://openapi.alipay.com/gateway.do)时,需要使用应用密钥。

由商户密钥与支付宝密钥交换后与支付宝商户标识(如partnerID、APPID等)绑定。





 

 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值