iOS开发总结--三方平台开发之微信支付
1.前言
现在很多应用都有支付功能,支付也是开发中比较麻烦的一个部分。其实,最麻烦的部分是商户帐号的审核,如果没有商户帐号,就没有你要给钱的那个对公账户。
2.关于交易
在这个金融类项目的开发中,接触了一些金融常识。比如,要是需要进行融资的话,必须要有对公账户,若没有对公账户,那么进行的融资交易即视为非法集资。而申请微信或支付宝的商家账户其实就是开通一个对公账户。但是,最烦人的就是申请账户,等待审核。
3.微信支付
I)业务流程

以上的图是微信官方的图,其实挺坑人的,时序图弄的那么麻烦。
其实简言之就两步:
1)下预支付订单,调用https://api.mch.weixin.qq.com/pay/unifiedorder 统一支付API
2)调起微信支付接口
II)接入微信SDK
微信的支付和微信分享是相同的SDK,再上一篇中已经把SDK引入到项目中不需要再引入了。新的SDK版本为1.6.2,去掉了之前版本预支付调用统一下单API的方法,当然,统一下单接口本来就应该后台调用,以便后台存储商户订单和微信后台的预支付订单。后台调用统一下单接口后,将后台存储的订单ID和预支付ID(prepayid)返回给iOS/Android移动端即可,以便移动端调起微信并让用户支付订单金额。
虽然,新版SDK去掉了预支付流程,但是为了
4.支付单例的设计
支付单例类似于分享单例。为什么要拆开到单独的类中?因为,单独拿出来以便今后再集成支付宝的支付。
I)头文件
//
// NYPaymentManager.h
// NYShare
//
// Created by 倪瑶 on 15/12/10.
// Copyright © 2015年 nycode. All rights reserved.
// #import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "NYXMLParser.h"
#import "NYWXPayUtility.h"
#import "WXApi.h"
//暂时用 创友
#define WX_PAY_APP_ID @"" /**< 微信开放应用APP ID !重要:必须是和商户关联的APP ID */
#define WX_PAY_APP_SECRET @"" /**< 微信开放应用APP SECRET */ #define WX_PAY_API_KEY @"" /**< API密钥*/
#define WX_PAY_PARTNER_ID @"" /**< 微信支付商户号 */
#define WX_PAY_DEVICE_INFO @"" /**< 支付设备号或门店号 */
#define WX_PAY_BILL_CREATE_IP @"192.168.0.1" /**< 发器支付的机器ip */
#define WX_PAY_NOTIFY_URL @"" /**< 回调URL,接收异步通知 */
#define WX_PAY_UNIFIEDORDER_API @"https://api.mch.weixin.qq.com/pay/unifiedorder" /**< 统一订单接口,详见https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=9_1 */
#define WX_PAY_PACKAGE @"Sign=WXPay" #define PAYMENT_ERROR_DOMAIN_WX_PREPAYID @"PAYMENT_ERROR_DOMAIN_WX_PREPAYID" //获取prepayid失败
#define PAYMENT_ERROR_DOMAIN_WX_SIGN @"PAYMENT_ERROR_DOMAIN_WX_SIGN" //服务器返回签名验证错误
#define PAYMENT_ERROR_DOMAIN_WX_SERVER @"PAYMENT_ERROR_DOMAIN_WX_SERVER" //请求接口返回错误
#define PAYMENT_ERROR_DOMAIN_WX_PRICE @"PAYMENT_ERROR_DOMAIN_WX_PRICE" //价格为负数
#define PAYMENT_ERROR_DOMAIN_WX_RESPONSE @"PAYMENT_ERROR_DOMAIN_WX_RESPONSE" //服务器返回对象为空
#define PAYMENT_ERROR_DOMAIN_WX_REQUEST @"PAYMENT_ERROR_DOMAIN_WX_REQUEST" //支付请求失败
#define PAYMENT_ERROR_DOMAIN_WX_RESULT_FAIL @"PAYMENT_ERROR_DOMAIN_WX_RESULT_FAIL"//返回失败
#define PAYMENT_ERROR_DOMAIN_WX_PAYFAILED @"PAYMENT_ERROR_DOMAIN_WX_PAYFAILED"//可能的原因:签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常等
#define PAYMENT_ERROR_DOMAIN_WX_PAYCANCELED @"PAYMENT_ERROR_DOMAIN_WX_PAYCANCELED"
/**
* 支付错误码类型
**/
typedef NS_ENUM(NSInteger, NYPaymentErrorCode) {
NYPaymentErrorCodeWeChatSignVerifyError,
NYPaymentErrorCodeWeChatApiResponseError,
NYPaymentErrorCodeWeChatGetPrePayIDFailed,
NYPaymentErrorCodeWeChatPriceLow,
NYPaymentErrorCodeWeChatResponseError,
NYPaymentErrorCodeWeChatRequestError,
NYPaymentErrorCodeWeChatResultCodeFail,
NYPaymentErrorCodeWeChatPayFailed,
NYPaymentErrorCodeWeChatPayCanceled,
NYPaymentErrorCodeWeChatPaySuccess,//暂不用,最好后台请求获取,以服务器饭或为准
NYPaymentErrorCodeALiPay,
}; /**
* 支付类型
**/
typedef NS_ENUM(NSInteger, NYPaymentType) {
NYPaymentTypeWeChat,
NYPaymentTypeALiPay,
}; /**
* 回调
* @param error 支付请求返回的错误
* @param requestObject 支付请求发送的对象
* @param responseObject 支付相应返回的对象
**/
typedef void(^NYPaymentComletion)(NSError *error, id requestObject, id responseObject); /**
* 支付订单对象
**/
@interface NYPaymentObject : NSObject
@property (strong, nonatomic) NSString *orderID; /**< 商户订单ID,商户后台提供 */
@property (strong, nonatomic) NSString *orderTitle; /**< 商户订单标题,商户后台提供 */
@property (strong, nonatomic) NSString *orderPrice; /**< 订单价格,单位为元 */
@property (strong, nonatomic) NSString *wxPrePayID; /**< 微信预支付订单号,微信支付时必填! */
@end
/**
* 支付通用类
**/
@interface NYPaymentManager : NSObject <WXApiDelegate>
@property (strong, nonatomic) NYPaymentComletion completion; /**< 回调 */ /**
* 单例
**/
+ (instancetype)defaultManager;
- (void)registerPaymentApp;
/**
* 微信移动端独立发送统一订单请求方法
* @param orderID 商户订单ID,商户后台提供
* @param orderTitle 商户订单标题,商户后台提供
* @param price 订单价格,单位为分
* @param completion 业务回调
* @brief 该方法用于没有后台请求统一下单接口的情况
* @description 仅供测试用
**/
//- (void)sendWeChatPrePayRequestWithOrderID:(NSString *)orderID orderTitle:(NSString *)orderTitle price:(NSString *)price completion:(NYPaymentComletion)completion;
/**
* 微信支付方法
* @param object 支付的订单对象
* @param completion 支付的回调方法
**/
- (void)payForWeChatWithOrderObject:(NYPaymentObject *)object completion:(NYPaymentComletion)completion;
/**
* 支付统一方法
* @param payType 支付类型,阿里支付、微信支付
* @param object 支付订单对象
* @param completion 回调函数
**/
- (void)payForType:(NYPaymentType)payType paymentObject:(NYPaymentObject *)object completion:(NYPaymentComletion)completion;
/**
* 分享打开三方应用代理回调方法
**/
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url;
/**
* 分享打开三方应用代理回调方法
**/
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation;
@end
II)实现文件
//
// NYPaymentManager.m
// NYShare
//
// Created by 倪瑶 on 15/12/10.
// Copyright © 2015年 nycode. All rights reserved.
// #import "NYPaymentManager.h" @implementation NYPaymentObject @end @implementation NYPaymentManager + (instancetype)defaultManager {
static NYPaymentManager *manager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
manager = [[self alloc] init];
});
return manager;
} - (instancetype)init {
self = [super init];
if (self) { }
return self;
} - (void)registerPaymentApp {
[WXApi registerApp:WX_PAY_APP_ID]; } #pragma mark - payment
- (void)payForType:(NYPaymentType)payType paymentObject:(NYPaymentObject *)object completion:(NYPaymentComletion)completion {
switch (payType) {
case NYPaymentTypeALiPay: { break;
}
case NYPaymentTypeWeChat: {
[[NYPaymentManager defaultManager] payForWeChatWithOrderObject:object completion:completion];
break;
}
default:
break;
}
} - (void)payTestForWeChatWithOrderObject:(NYPaymentObject *)object completion:(NYPaymentComletion)completion {
NSString *centPrice = [NSString stringWithFormat:@"%.f",object.orderPrice.floatValue*]; [self sendWeChatPrePayRequestWithOrderID:object.orderID orderTitle:object.orderTitle price:centPrice completion:^(NSError *error, id requestObject, id responseObject) {
if (error != nil) {
// NSLog(@"Domain:%@\n Description:%@\n request:%@\n", error.domain, error.description, requestObject);
if (completion != nil) {
completion(error, requestObject, nil);
}
} else { if (centPrice.floatValue < ) {
NSError *error = [NSError errorWithDomain:PAYMENT_ERROR_DOMAIN_WX_PRICE code:NYPaymentErrorCodeWeChatPriceLow userInfo:@{NSLocalizedDescriptionKey:[NSString stringWithFormat:@"价格为负数!"]}];
if (completion != nil) {
completion(error, nil, nil);
}
} else {
if (responseObject != nil) {
NSString *time_stamp, *nonce_str;
//设置支付参数
time_t now;
time(&now);
time_stamp = [NSString stringWithFormat:@"%ld", now];
nonce_str = [NYWXPayUtility md5:time_stamp];
//支付请求的参数一定要核对清楚
PayReq *payRequest = [[PayReq alloc] init];
payRequest.openID = WX_PAY_APP_ID;
payRequest.partnerId = WX_PAY_PARTNER_ID;
payRequest.prepayId = [responseObject objectForKey:@"prepayid"];//!!!!
payRequest.nonceStr = nonce_str;
payRequest.timeStamp = time_stamp.intValue;
payRequest.package = WX_PAY_PACKAGE;//???? //第二次签名参数列表
NSMutableDictionary *signParams = [NSMutableDictionary dictionary];
[signParams setObject: WX_PAY_APP_ID forKey:@"appid"];
[signParams setObject: nonce_str forKey:@"noncestr"];
[signParams setObject: WX_PAY_PACKAGE forKey:@"package"];
[signParams setObject: WX_PAY_PARTNER_ID forKey:@"partnerid"];
[signParams setObject: time_stamp forKey:@"timestamp"];
[signParams setObject: [responseObject objectForKey:@"prepayid"] forKey:@"prepayid"];
//[signParams setObject: @"MD5" forKey:@"signType"];
//生成签名
NSString *sign = [self createMd5Sign:signParams];
payRequest.sign = sign;//????
BOOL status = [WXApi sendReq:payRequest];
if (!status) {
NSError *error = [NSError errorWithDomain:PAYMENT_ERROR_DOMAIN_WX_REQUEST code:NYPaymentErrorCodeWeChatRequestError userInfo:@{NSLocalizedDescriptionKey:@"支付请求失败!"}];
if (completion != nil) {
completion(error, nil, nil);
}
} else {
if (completion != nil) {
completion(nil, nil, nil);
}
} } else {
NSError *error = [NSError errorWithDomain:PAYMENT_ERROR_DOMAIN_WX_RESPONSE code:NYPaymentErrorCodeWeChatResponseError userInfo:@{NSLocalizedDescriptionKey:@"服务器返回对象为空!"}];
if (completion != nil) {
completion(error, nil, nil);
}
}
} }
}];
} - (void)payForWeChatWithOrderObject:(NYPaymentObject *)object completion:(NYPaymentComletion)completion {
if (object.wxPrePayID.length == ) {
NSError *error = [NSError errorWithDomain:PAYMENT_ERROR_DOMAIN_WX_PREPAYID code:NYPaymentErrorCodeWeChatGetPrePayIDFailed userInfo:@{NSLocalizedDescriptionKey:@"获取prepayid失败!\n"}];
if (completion != nil) {
completion(error, nil, nil);
}
} else {
NSString *time_stamp, *nonce_str;
//设置支付参数
time_t now;
time(&now);
time_stamp = [NSString stringWithFormat:@"%ld", now];
nonce_str = [NYWXPayUtility md5:time_stamp];
//支付请求的参数一定要核对清楚
PayReq *payRequest = [[PayReq alloc] init];
payRequest.openID = WX_PAY_APP_ID;
payRequest.partnerId = WX_PAY_PARTNER_ID;
payRequest.prepayId = object.wxPrePayID;//!!!!
payRequest.nonceStr = nonce_str;
payRequest.timeStamp = time_stamp.intValue;
payRequest.package = WX_PAY_PACKAGE;//???? //第二次签名参数列表
NSMutableDictionary *signParams = [NSMutableDictionary dictionary];
[signParams setObject: WX_PAY_APP_ID forKey:@"appid"];
[signParams setObject: nonce_str forKey:@"noncestr"];
[signParams setObject: WX_PAY_PACKAGE forKey:@"package"];
[signParams setObject: WX_PAY_PARTNER_ID forKey:@"partnerid"];
[signParams setObject: time_stamp forKey:@"timestamp"];
[signParams setObject: object.wxPrePayID forKey:@"prepayid"];
//[signParams setObject: @"MD5" forKey:@"signType"];
//生成签名
NSString *sign = [self createMd5Sign:signParams];
payRequest.sign = sign;//????
BOOL status = [WXApi sendReq:payRequest];
if (!status) {
NSError *error = [NSError errorWithDomain:PAYMENT_ERROR_DOMAIN_WX_REQUEST code:NYPaymentErrorCodeWeChatRequestError userInfo:@{NSLocalizedDescriptionKey:@"支付请求失败!"}];
if (completion != nil) {
completion(error, nil, nil);
}
} else {
if (completion != nil) {
completion(nil, nil, nil);
}
}
}
} - (void)sendWeChatPrePayRequestWithOrderID:(NSString *)orderID orderTitle:(NSString *)orderTitle price:(NSString *)price completion:(NYPaymentComletion)completion {
self.completion = completion;
NSMutableDictionary *preOrder = [NSMutableDictionary dictionary];
srand( (unsigned)time() );
NSString *noncestr = [NSString stringWithFormat:@"%d", rand()]; [preOrder setObject: WX_PAY_APP_ID forKey:@"appid"]; //开放平台appid
[preOrder setObject: WX_PAY_PARTNER_ID forKey:@"mch_id"]; //商户号
[preOrder setObject: WX_PAY_DEVICE_INFO forKey:@"device_info"]; //支付设备号或门店号
[preOrder setObject: noncestr forKey:@"nonce_str"]; //随机串
[preOrder setObject: @"APP" forKey:@"trade_type"]; //支付类型,固定为APP
[preOrder setObject: orderTitle forKey:@"body"]; //订单描述,展示给用户
[preOrder setObject: WX_PAY_NOTIFY_URL forKey:@"notify_url"]; //支付结果异步通知
[preOrder setObject: orderID forKey:@"out_trade_no"];//商户订单号
[preOrder setObject: WX_PAY_BILL_CREATE_IP forKey:@"spbill_create_ip"];//发器支付的机器ip
[preOrder setObject: price forKey:@"total_fee"]; //订单金额,单位为分 NSString *prePayID = [self getPrePayIDWithPrePayOrder:preOrder];
if (prePayID.length != ) { NSString *package, *time_stamp, *nonce_str;
//设置支付参数
time_t now;
time(&now);
time_stamp = [NSString stringWithFormat:@"%ld", now];
nonce_str = [NYWXPayUtility md5:time_stamp];
//重新按提交格式组包,微信客户端暂只支持package=Sign=WXPay格式,须考虑升级后支持携带package具体参数的情况
//package = [NSString stringWithFormat:@"Sign=%@",package];
package = WX_PAY_PACKAGE;
//第二次签名参数列表
NSMutableDictionary *signParams = [NSMutableDictionary dictionary];
[signParams setObject: WX_PAY_APP_ID forKey:@"appid"];
[signParams setObject: nonce_str forKey:@"noncestr"];
[signParams setObject: package forKey:@"package"];
[signParams setObject: WX_PAY_PARTNER_ID forKey:@"partnerid"];
[signParams setObject: time_stamp forKey:@"timestamp"];
[signParams setObject: prePayID forKey:@"prepayid"];
//[signParams setObject: @"MD5" forKey:@"signType"];
//生成签名
NSString *sign = [self createMd5Sign:signParams]; //添加签名
[signParams setObject: sign forKey:@"sign"];
if (self.completion != nil) {
self.completion(nil, nil, signParams);
} } else {
NSError *error = [NSError errorWithDomain:PAYMENT_ERROR_DOMAIN_WX_PREPAYID code:NYPaymentErrorCodeWeChatGetPrePayIDFailed userInfo:@{NSLocalizedDescriptionKey:@"获取prepayid失败!\n"}];
if (self.completion != nil) {
self.completion(error, preOrder, nil);
}
} } - (NSString *)getPrePayIDWithPrePayOrder:(NSMutableDictionary *)preOrder {
NSString *prePayID = nil;
NSString *packageSign = [self packageSign:preOrder]; NSData *response = [NYWXPayUtility postSynchronousRequestWithURL:WX_PAY_UNIFIEDORDER_API httpBody:packageSign];
NYXMLParser *xml = [[NYXMLParser alloc] init];
[xml parseData:response];
NSMutableDictionary *dictionary = [xml dictionary];
//判断返回
NSString *return_code = [dictionary objectForKey:@"return_code"];
NSString *return_msg = [dictionary objectForKey:@"return_msg"];
NSString *result_code = [dictionary objectForKey:@"result_code"];
NSString *err_code = [dictionary objectForKey:@"err_code"];
NSString *err_code_des = [dictionary objectForKey:@"err_code_des"];
if ( [return_code isEqualToString:@"SUCCESS"] ) {
//生成返回数据的签名
NSString *sign = [self createMd5Sign:dictionary ];
NSString *send_sign =[dictionary objectForKey:@"sign"] ; //验证签名正确性
if( [sign isEqualToString:send_sign]){
if( [result_code isEqualToString:@"SUCCESS"]) {
//验证业务处理状态
prePayID = [dictionary objectForKey:@"prepay_id"];
return_code = ;
// if (self.completion != nil) {
// self.completion(nil, nil, nil);
// }
// [debugInfo appendFormat:@"获取预支付交易标示成功!\n"];
} else {
NSError *error = [NSError errorWithDomain:PAYMENT_ERROR_DOMAIN_WX_RESULT_FAIL code:NYPaymentErrorCodeWeChatResultCodeFail userInfo:@{NSLocalizedDescriptionKey:[NSString stringWithFormat:@"获得prepayid失败, %@, %@", err_code, err_code_des]}];
if (self.completion != nil) {
self.completion(error, nil, nil);
}
}
} else {
NSError *error = [NSError errorWithDomain:PAYMENT_ERROR_DOMAIN_WX_SIGN code:NYPaymentErrorCodeWeChatSignVerifyError userInfo:@{NSLocalizedDescriptionKey:[NSString stringWithFormat: @"服务器返回签名验证错误!!!\n返回信息:%@", return_msg]}];
if (self.completion != nil) {
self.completion(error, send_sign, nil);
}
// last_errcode = 1;
// [debugInfo appendFormat:@"gen_sign=%@\n _sign=%@\n",sign,send_sign];
// [debugInfo appendFormat:@"服务器返回签名验证错误!!!\n"]; }
} else {
NSError *error = [NSError errorWithDomain:PAYMENT_ERROR_DOMAIN_WX_SERVER code:NYPaymentErrorCodeWeChatSignVerifyError userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat: @"请求接口返回错误!!!\n返回信息:%@", return_msg]}];
if (self.completion != nil) {
self.completion(error, packageSign, nil);
} // last_errcode = 2;
// [debugInfo appendFormat:@"接口返回错误!!!\n"];
}
return prePayID;
}
//获取package带参数的签名包
- (NSString *)packageSign:(NSMutableDictionary *)packageParams {
NSString *sign;
NSMutableString *reqPars = [NSMutableString string];
//生成签名
sign = [self createMd5Sign:packageParams];
//生成xml的package
NSArray *keys = [packageParams allKeys];
NSArray *sortedArray = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [obj1 compare:obj2 options:NSNumericSearch];
}];
[reqPars appendString:@"<xml>\n"];
for (NSString *categoryId in sortedArray) {
[reqPars appendFormat:@"<%@>%@</%@>\n", categoryId, [packageParams objectForKey:categoryId],categoryId];
}
[reqPars appendFormat:@"<sign>%@</sign>\n</xml>", sign]; return [NSString stringWithString:reqPars];
}
/**
* 具体签名加密方法见 https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=4_3
**/
- (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=%@", WX_PAY_API_KEY];
//得到MD5 sign签名
NSString *md5Sign =[NYWXPayUtility md5:contentString]; return md5Sign;
} - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
BOOL result = NO;
if ([url.scheme isEqualToString:[NSString stringWithFormat:@"%@", WX_PAY_APP_ID]]) {
result = [WXApi handleOpenURL:url delegate:self];
}
return result;
} - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
BOOL result = NO;
if ([url.scheme isEqualToString:[NSString stringWithFormat:@"%@", WX_PAY_APP_ID]]) {
result = [WXApi handleOpenURL:url delegate:self];
}
return result;
} #pragma mark - wechat delegate - (void)onReq:(BaseReq *)req { } - (void)onResp:(BaseResp *)resp {
if ([resp isKindOfClass:[PayResp class]]) {
PayResp *paymentResponse = (PayResp *)resp;
switch (paymentResponse.errCode) {
case : { break;
}
case -: {
NSError *error = [NSError errorWithDomain:PAYMENT_ERROR_DOMAIN_WX_PAYFAILED code:NYPaymentErrorCodeWeChatPayFailed userInfo:@{NSLocalizedDescriptionKey:@"支付失败,可能的原因:签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常等"}];
if (self.completion != nil) {
self.completion(error, nil, nil);
}
break;
}
case -: {
NSError *error = [NSError errorWithDomain:PAYMENT_ERROR_DOMAIN_WX_PAYCANCELED code:NYPaymentErrorCodeWeChatPayCanceled userInfo:@{NSLocalizedDescriptionKey:@"用户取消支付"}];
if (self.completion != nil) {
self.completion(error, nil, nil);
}
break;
}
default:
break;
}
}
} @end
iOS开发总结--三方平台开发之微信支付的更多相关文章
- iOS开发总结--三方平台开发之分享
1.前言 在公司参与了多个应用三方平台的开发,涉及微信.微博.QQ.Facebook.meetup等,总结一下一般的接入三方平台SDK方法. 2.接入三方SDK 任何应用要接入三方平台,都需要在该平台 ...
- 微信公众平台开发教程--方培工作室,PHP语言版本
准备工作 微信公众平台的注册 介绍如何注册一个微信公众账号. 入门教程 微信公众平台开发入门教程 内容:1.申请SAE作为服务器; 2.启用开发模式; 3.微信公众平台PHP SDK; 4.接收发送消 ...
- C#开发微信门户及应用(32)--微信支付接入和API封装使用
在微信的应用上,微信支付是一个比较有用的部分,但也是比较复杂的技术要点,在微商大行其道的年代,自己的商店没有增加微信支付好像也说不过去,微信支付旨在为广大微信用户及商户提供更优质的支付服务,微信的支付 ...
- NET微信公众号开发-5.0微信支付(待测试)
开发前准备. 1.0微信支付官方开发者文档 2.0官方demo下载 我们用c#所以选择.net版本 不过这个官方的demo根本跑步起来 3.0官方demo运行起来解决方案 4.0微信支付官方.net版 ...
- PHP微信支付开发实例
这篇文章主要为大家详细介绍了PHP微信支付开发过程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 PHP微信支付开发过程,分享给大家,供大家参考,具体内容如下 1.开发环境 Thinkphp 3. ...
- .NET微信公众号开发-5.0微信支付
一.前言 在开始做这个功能之前,我们要做的第一件事情就是思考,如何做这个微信支付,从哪里开始,从哪里入手,官方的sdk说明什么的,有没有什么官方的demo,还有就是老板给我的一些资料齐全不,那些要申请 ...
- php微信支付(仅pc端扫码支付模式二)详细步骤.----仅适合第一次做微信开发的程序员
本人最近做了微信支付开发,是第一次接触.其中走了很多弯路,遇到的问题也很多.为了让和我一样的新人不再遇到类似的问题,我把我的开发步骤和问题写出来,以供参考. 开发时间是2016/8/10,所以微信支付 ...
- php微信支付(仅Jsapi支付)详细步骤.----仅适合第一次做微信开发的程序员
本人最近做了微信支付开发,是第一次接触.其中走了很多弯路,遇到的问题也很多.为了让和我一样的新人不再遇到类似的问题,我把我的开发步骤和问题写出来,以供参考. 开发时间是2016/8/2,所以微信支付的 ...
- PHP后台支付的开发:微信支付和支付宝支付
关于支付的流程之类的就不做解释,大家可以自行搜索! 微信支付 项目前提:本人用的是tp框架,PHP语言下载到微信平台提供的微信支付接口文件,放在了tp第三方类库vendor,命名为WxpayAPI, ...
随机推荐
- java利用递归实现汉诺塔算法
package 汉诺塔; //引入Scanner包,用于用户输入 import java.util.Scanner; public class 汉诺塔算法 { public static void m ...
- 实现KbmMw web server 支持https
在以前的文章里面介绍过kbmmw 做web server. 前几天红鱼儿非要我给他做一个支持https 的web server. 其实kbmmw 支持https 有好几种方法: 1. 使用isapi ...
- 利用ajaxSubmit()方法实现Form提交表单后回调
1. 背景 最近在工作中,需要实现网页端图片上传到FTP服务器的功能.上传文件是用Form表单提交数据的方法向后台传输文件流,在此遇到了一个问题:后台在处理完图片上传功能后,需要向前台回传是 ...
- UVaLive 4597 Inspection (网络流,最小流)
题意:给出一张有向图,每次你可以从图中的任意一点出发,经过若干条边后停止,然后问你最少走几次可以将图中的每条边都走过至少一次,并且要输出方案,这个转化为网络流的话,就相当于 求一个最小流,并且存在下界 ...
- (最长回文串 模板) 最长回文 -- hdu -- 3068
http://acm.hdu.edu.cn/showproblem.php?pid=3068 最长回文 Time Limit: 4000/2000 MS (Java/Others) Memory ...
- Beta版本使用说明
一.产品介绍 我们做的是一个基于安卓的手机app,通过连接图书馆的数据库,实现查询图书馆的书目信息的功能. 二.软件运行 我们只做了安卓版本,需要在安卓环境下运行. 三.软件结构 本软件主要包括客户端 ...
- Windows Server 2008 R2远程桌面服务配置和授权激活
远程桌面服务安装好之后使用的是120天临时授权,所以会跳出以下提示,我们介绍远程桌面授权的激活. 现在我们使用命令 mstsc /admin 强制登录服务器 需要在“远程桌面服务”--安装“远程桌面授 ...
- Android中设置分割线
设置分隔线的方法一: 在需要设置分隔线的布局文件中加入如下代码: <View android:layout_width="fill_parent" andr ...
- Checkpoint--相关问题
Checkpoint是实例级别还是数据库级别? 答:数据库级别,在SQL Server关闭时,会对所有数据库逐一提交checkpoint 测试代码 USE DB0002 GO CHECKPOINT G ...
- Source Multiplayer Networking【转】
https://developer.valvesoftware.com/wiki/Source_Multiplayer_Networking Multiplayer games based on th ...