---恢复内容开始---

APP支付(.NET版)

一、   支付宝支付

1、 有一个支付账号,在蚂蚁金服开放平台中登录账号→选择“管理中心”→在“开发者中心”下选择“网页&移动应用”→然后按步骤创建应用→选择需要的功能进行签约,签约成功后即可使用。

(注意事项:在签约的时候生成的私钥、公钥、还有支付宝公钥记得将文件保存。

支付签约成功会以手机短讯的方式进行通知,这时请查看你的邮箱(在签约时预留的),打开支付发送过来的邮件,通过里面的链接地址进行二次确认,才可正式签约生效)

2、 从官网下载“.NET版”SDK

3、 将SDK添加引用到项目

4、 获取预订单号,返回的预订单号直接给app端请求支付宝,不用做处理---代码如下:

/// <summary>

/// 获取预订单编号

/// </summary>

/// <param name="money">支付金额</param>

/// <param name="tradeNo">本地订单号</param>

/// <param name="payment">取卡收费,注册收费</param>这个参数可以不用,是根据自己需要加上的

public string GetOrderId(string money, string tradeNo, string payment)

{

string orderId = string.Empty;

try

{

if (!string.IsNullOrEmpty(payment))

{

//正式环境

IAopClient client = new DefaultAopClient(AlPayConfig.payUrl

, AlPayConfig.aPPID, AlPayConfig.alipayprivateKey, "json", "1.0", "RSA2"

, AlPayConfig.alipaypublicKey, AlPayConfig.charset, false);

//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称如:alipay.trade.app.pay

AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();

//SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。

AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();

model.Body = "支付宝付款";   //对一笔交易的具体描述信息。如果是多种商品,请将商品描述字符串累加传给body。

model.Subject = payment;//商品的标题/交易标题/订单标题/订单关键字等。

model.TotalAmount = money;//订单总金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000]

model.ProductCode = "QUICK_MSECURITY_PAY";//销售产品码,商家和支付宝签约的产品码,为固定值QUICK_MSECURITY_PAY

model.OutTradeNo = CommonMethod.StringRemove_(tradeNo);//商户网站唯一订单号

model.TimeoutExpress = "30m";//该笔订单允许的最晚付款时间,逾期将关闭交易。取值范围:1m~15d。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。 该参数数值不接受小数点, 如 1.5h,可转换为 90m。注:若为空,则默认为15d。

request.SetBizModel(model);

request.SetNotifyUrl(AlPayConfig.notifyUrl);//外网商户可以访问的异步地址

//这里和普通的接口调用不同,使用的是sdkExecute

AlipayTradeAppPayResponse response = client.SdkExecute(request);

//HttpUtility.HtmlEncode是为了输出到页面时防止被浏览器将关键参数html转义,实际打印到日志以及http传输不会有这个问题

//Response.Write(HttpUtility.HtmlEncode(response.Body));

//页面输出的response.Body就是orderString 可以直接给客户端请求,无需再做处理。

string aa = response.TradeNo;

orderId = response.Body;

}

}

catch (Exception e)

{

Log.Error("AlPay", "App支付支付回调通知:" + e.Message);

}

return orderId;

}

请求参数请参考“https://docs.open.alipay.com/204/105465/

5、 支付宝异步回调,返回支付结果及参数(参数描述请参考“https://docs.open.alipay.com/204/105301/”)

A、 获取返回的参数信息,并转换成字典

/// 获取支付宝POST过来通知消息,并以“参数名=参数值”的形式组成数组

/// request回来的信息组成的数组

public IDictionary<string, string> GetRequestPost()

{

int i = 0;

IDictionary<string, string> sArray = new Dictionary<string, string>();

NameValueCollection coll;

//Load Form variables into NameValueCollection variable.

coll = Request.Form;

// Get names of all forms into a string array.

string[] requestItem = coll.AllKeys;

for (i = 0; i < requestItem.Length; i++)

{

sArray.Add(requestItem[i], Request.Form[requestItem[i]]);

}

return sArray;

}

B、确认是否支付成功

/// <summary>

/// App支付支付回调通知,判断是否支付成功

/// </summary

public void AppPayNotify(IDictionary<string, string> strArray)

{

//string result = string.Empty;

try

{

//切记alipaypublickey是支付宝的公钥,请去open.alipay.com对应应用下查看。

//bool RSACheckV1(IDictionary<string, string> parameters, string alipaypublicKey, string charset, string signType, bool keyFromFile)

bool flag = AlipaySignature.RSACheckV1(strArray, AlPayConfig.alipaypublicKey, AlPayConfig.charset, "RSA2", false);

if (!UpdateData(strArray, flag))

{

CommonMethod.WriteErrorLog(string.Format(CommonMethod.LOG_ERROR_FORMAT, this.GetType().FullName,

new System.Diagnostics.StackTrace().GetFrame(0).GetMethod().Name, "支付宝支付回调完成后修改数据失败!"));

}

}

catch (Exception e)

{

Log.Error("AlPay", "App支付回调通知:" + e.Message);

}

}

6、 根据服务器订单号判断是否支付成功(也可以是根据支付订单号查询支付结果)

/// <summary>

/// 根据订单号返回支付结果

/// </summary>

public AlipayTradeQueryResponse GetPayResultByPreOrderId(string orderId)

{

orderId = CommonMethod.StringRemove_(orderId);

//正式环境

IAopClient client = new DefaultAopClient(AlPayConfig.payUrl

, AlPayConfig.aPPID, AlPayConfig.alipayprivateKey, "json", "1.0", "RSA2",

AlPayConfig.alipaypublicKey, AlPayConfig.charset, false);

AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();

request.BizContent = "{\"out_trade_no\":\""+ orderId + "\"," +

"\"trade_no\":\"\"}";

//string.Format(@"{ut_trade_no:{0},trade_no:""}", orderId);

AlipayTradeQueryResponse response = client.Execute(request);

//Console.WriteLine(response.Body);

return response;

}

/// <summary>

/// 根据服务器订单号判断是否支付成功

/// </summary>

/// <param name="orderId">服务器订单号</param>

private void AlTestPayByOrderID(string orderId)

{

try

{

//根据服务器订单号返回支付结果

AlipayTradeQueryResponse response = new AlPay().GetPayResultByPreOrderId(orderId);

T_TMM_RFCardPaymentService rfCardPaymentService = new T_TMM_RFCardPaymentService();

//根据TradeStatus交易状态:WAIT_BUYER_PAY(交易创建,等待买家付款)

//TRADE_CLOSED(未付款交易超时关闭,或支付完成后全额退款)、TRADE_SUCCESS(交易支付成功)、TRADE_FINISHED(交易结束,不可退款)

if (response.TradeStatus.ToUpper() == "TRADE_SUCCESS")//如果支付成功,则修改数据状态

{

string tradeNoR = response.TradeNo;//支付宝交易号

string outTradeNo = CommonMethod.StringToGuidStr(response.OutTradeNo);//商户订单号(服务器订单号)

string buyerLogonId = response.BuyerLogonId;//买家支付宝账号

string paymentDate = response.SendPayDate;//交易付款时间

string payStatus = "1";//支付成功状态为1,失败为2

rfCardPaymentService.PaySuccess(outTradeNo, "1", tradeNoR, buyerLogonId, paymentDate, payStatus);

}

else

{

//将订单改为失效订单

rfCardPaymentService.SetOrderInvalid(orderId);

}

}

catch (Exception ex)

{

CommonMethod.WriteErrorLog(string.Format(CommonMethod.LOG_ERROR_FORMAT, this.GetType().FullName,

new System.Diagnostics.StackTrace().GetFrame(0).GetMethod().Name, ex.Message));

}

}

二、   微信支付

1、 有微信账号及微信商户号

2、 使用微信账号登录微信开放平台,创建移动应用,根据步骤填写详细信息。等待认证通过,平台认证需要付费。

3、 在微信商户平台创建商户账号,商户账号绑定银行卡,作为APP支付的目标账户。

4、 获取预订单号

/// <summary>

/// 取得预支付ID

/// </summary>

/// <param name="money">订单金额</param>

/// <param name="out_trade_no">订单编号</param>

/// <param name="body">商品描述交易字段</param>

/// <returns></returns>

private WxPayData PrepayId(double money, string tradeNo, string body)

{

WxPayData data = new WxPayData();

data.SetValue("body", body);//商品描述交易字段格式根据不同的应用场景按照以下格式:APP——需传入应用市场上的APP名字 - 实际商品名称,天天爱消除 - 游戏充值。

string out_trade_no = tradeNo.Replace("-", "");//微信要求商户订单号不能超过32位

data.SetValue("out_trade_no", out_trade_no);//商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*@ ,且在同一个商户号下唯一。

data.SetValue("total_fee", (int)(money * 100));//总金额:订单总金额,单位为分,int类型

string ip = Request.UserHostAddress;

data.SetValue("spbill_create_ip", ip);//用户端实际ip

data.SetValue("notify_url", WxPayConfig.NOTIFY_URL);//支付成功回调地址

data.SetValue("trade_type", "APP");//交易类型

data.SetValue("attach", body);//附加数据,交易完成,原样返回,body参数不返回,所以用这个代替

WxPayData result = new WxPayData();

try

{

result = WxPayApi.UnifiedOrder(data);//调用统一下单接口

}

catch (System.Exception ex)

{

result.SetValue("return_code", "FAIL");

result.SetValue("return_msg", "下单失败,请返回重试。");

CommonMethod.WriteErrorLog(string.Format(CommonMethod.LOG_ERROR_FORMAT, this.GetType().FullName,

new System.Diagnostics.StackTrace().GetFrame(0).GetMethod().Name, ex.Message));

}

//result.SetValue("return_code", "SUCCEED");//返回的结果已经包含当前字段

//res.Data = result.ToJson();

return result;

}

5、 微信回调修改本地数据库

/// <summary>

/// 微信支付支付结果通知处理

/// </summary>

//[HttpPost, ValidateInput(false)]

[HttpPost]

public void ProcessNotify()

{

try

{

WxResultNotify resultNotify = new WxResultNotify(this.Request, this.Response);

bool bPayRs = resultNotify.ProcessNotify();

WxPayData notifyData = resultNotify.NotifyData;

string id = string.Empty;//服务器订单号

string paymentOrderNo = string.Empty;//微信订单号

string paymentStatus = string.Empty;//支付状态

string paymentMethod = CommonConst.PayTypeWX;//支付方式

string paymentAccount = string.Empty;//用户编号

string payDate = string.Empty;//支付时间

//支付id

if (notifyData.IsSet("out_trade_no"))

{

string out_trade_no = notifyData.GetValue("out_trade_no").ToString();

if (string.IsNullOrEmpty(out_trade_no) || out_trade_no.Length != 32)//订单编号不正确

{

id = string.Empty;

return;

}

else

{

//还原订单号

StringBuilder sb = new StringBuilder();

sb.Append(out_trade_no.Substring(0, 8));

sb.Append("-");

sb.Append(out_trade_no.Substring(8, 4));

sb.Append("-");

sb.Append(out_trade_no.Substring(12, 4));

sb.Append("-");

sb.Append(out_trade_no.Substring(16, 4));

sb.Append("-");

sb.Append(out_trade_no.Substring(20, 12));

id = sb.ToString();

}

}

else

{

CommonMethod.WriteErrorLog(string.Format(CommonMethod.LOG_ERROR_FORMAT, this.GetType().FullName,

new System.Diagnostics.StackTrace().GetFrame(0).GetMethod().Name, "订单号不存在!"));

return;

}

//微信支付订单号

if (notifyData.IsSet("transaction_id"))

{

paymentOrderNo = notifyData.GetValue("transaction_id").ToString();

}

//用户编号

if (notifyData.IsSet("openid"))

{

paymentAccount = notifyData.GetValue("openid").ToString();

}

//支付时间

if (notifyData.IsSet("time_end"))

{

payDate = DateTime.ParseExact(notifyData.GetValue("time_end").ToString()

, "yyyyMMddHHmmss", System.Globalization.CultureInfo.CurrentCulture).ToString("yyyy-MM-dd HH:mm:ss");

}

//判断交易是否成功

if (notifyData.IsSet("result_code") && notifyData.GetValue("result_code").ToString() == "SUCCESS")//交易成功

{

paymentStatus = "1";//支付状态“成功”

}

else//交易失败

{

paymentStatus = "2"; //支付状态“失败”

CommonMethod.WriteErrorLog(string.Format(CommonMethod.LOG_ERROR_FORMAT, this.GetType().FullName,

new System.Diagnostics.StackTrace().GetFrame(0).GetMethod().Name, "交易失败!"));

}

//判断是取卡支付还是注册支付

if (notifyData.IsSet("attach") && notifyData.GetValue("attach").ToString().Contains(CommonConst.PaymentQK))//取卡支付

{

//支付完成修改数据

new T_TMM_RFCardPaymentService().PaySuccess(id, paymentMethod, paymentOrderNo, paymentAccount, payDate, paymentStatus);

}

else

{

//支付完成修改数据

new T_TMM_RegisterPaymentService().PaySuccess(id, paymentMethod, paymentOrderNo, paymentAccount, payDate, paymentStatus);

new AlPay().GreateLoginAuthorityByOrderId(id);

}

}

catch (Exception ex)

{

CommonMethod.WriteErrorLog(string.Format(CommonMethod.LOG_ERROR_FORMAT, this.GetType().FullName,

new System.Diagnostics.StackTrace().GetFrame(0).GetMethod().Name, ex.Message));

}

}

6、 根据服务器订单号查询是否支付成功(也可以根据支付订单号查询支付结果)

/// <summary>

/// 根据服务器订单号判断是否支付成功

/// </summary>

/// <param name="orderId">服务器订单号</param>

private void WXTestPayByOrderID(string orderId)

{

try

{

T_TMM_RFCardPaymentService rfCardPaymentService = new T_TMM_RFCardPaymentService();

//根据服务器订单号返回支付结果

WxPayData payData = new WxPayData();

payData.SetValue("out_trade_no", CommonMethod.StringRemove_(orderId));//服务器订单号

//返回查询结果

WxPayData payResult = WxPayApi.OrderQuery(payData);

//根据支付状态判断是否支付成功SUCCESS—支付成功REFUND—转入退款NOTPAY—未支付CLOSED—已关闭REVOKED—已撤销(刷卡支付)USERPAYING--用户支付中PAYERROR--支付失败(其他原因,如银行返回失败)

if (payResult.IsSet("trade_state") && payResult.GetValue("trade_state").ToString() == "SUCCESS")//支付成功

{

string tradeNoR = payResult.GetValue("transaction_id").ToString();//微信支付订单号

string outTradeNo = CommonMethod.StringToGuidStr(payResult.GetValue("out_trade_no").ToString());//商户订单号(服务器订单号)

string buyerLogonId = payResult.GetValue("openid").ToString();//买家支付宝账号

string paymentDate = DateTime.ParseExact(payResult.GetValue("time_end").ToString(),"yyyyMMddHHmmss", System.Globalization.CultureInfo.CurrentCulture).ToString("yyyy-MM-dd HH:mm:ss"); //交易付款时间

string payStatus = "1";//支付成功状态为1,失败为2

rfCardPaymentService.PaySuccess(outTradeNo, "2", tradeNoR, buyerLogonId, paymentDate, payStatus);

}

else//支付失败

{

//将订单改为失效订单

rfCardPaymentService.SetOrderInvalid(orderId);

}

}

catch (Exception ex)

{

CommonMethod.WriteErrorLog(string.Format(CommonMethod.LOG_ERROR_FORMAT, this.GetType().FullName,

new System.Diagnostics.StackTrace().GetFrame(0).GetMethod().Name, ex.Message));

}

}

注:微信开放平台创建移动应用时,开发信息中的以下信息是固定值,不能随意更换。

(如需修改,则必须通知APP开发人员,对APP作出相对应的修改)

iOS平台

iPhone

应用下载地址:未填写

Bundle ID:moon.SundyApp

测试版本Bundle ID:moon.SundyApp

iPad 无

Android平台

应用下载地址:未填写

应用签名:478c16ede90213492d8ea8eda87d1ada

包名:com.sundy.android

三、  所有与支付相关的配置信息,都在web.config文件中配置(重要)

1、 支付宝需配置的信息有

a)       AL_APPID 在支付宝的管理平台“创建应用”成功后,对于已经创建的应用会生成一个APPID,这个编号是唯一的,相当于应用的身份证号。

b)       AL_PUBLIC_KEY(支付宝公钥)在支付宝的管理平台“创建应用”成功后,在应用信息里面,有查看支付宝公钥的链接,将这个链接复制替换到config文件中,注意:不能出现换行和空格。

c)       AL_PRIVATE_KEY(应用私钥)在支付宝“创建应用”的时候,在使用“生成密钥”的工具生成时会生成两个txt文件,分别为“应用公钥”和“应用私钥”。这里使用的就是应用私钥。(注:“应用私钥”在“应用信息”中看不到)。

d)       CHARSET(编码格式)一般使用UTF-8。

e)       NOTIFY_URL回调地址(服务器地址)。

f)        AL_PAY_URL(支付宝-URL) 正式地址:https://openapi.alipay.com/gateway.do,沙箱环境:https://openapi.alipaydev.com/gateway.do

2、 微信需配置的信息有

a)  WX_URL_UNIFIEDORDER(统一下单url):https://api.mch.weixin.qq.com/pay/unifiedorder

b)  WX_URL_ORDERQUERY(订单查询url):https://api.mch.weixin.qq.com/pay/orderquery

c)  WX_URL_REPORT(测速上报url):https://api.mch.weixin.qq.com/payitil/report

d)  WX_APPID 在微信开放平台创建好应用后,生成的一个APPID。

e)  WX_MCHID(商户号)在微信商户平台注册的微信商户编号,用来指定收款帐户。

f)  WX_APIKEY(商户支付密钥)在微信商户平台注册的时间可以得到。

g)  WX_REPORT_LEVENL(上报信息配置 测速上报等级,0.关闭上报; 1.仅错误时上报; 2.全量上报)。

h)  WX_LOG_LEVENL(日志级别 日志等级,0.不输出日志;1.只输出错误信息; 2.输出错误和正常信息; 3.输出错误信息、正常信息和调试信息)。

3、 NOTIFY_URL(共用的回调URL,回调地址(服务器地址))

---恢复内容结束---

APP支付(.NET版)的更多相关文章

  1. 微信、支付宝App支付-JPay0.0.2发布

    JPay 对微信App支付.支付宝App支付的二次封装,对外提供一个相对简单的接口以及支付结果的回调 GitHub:https://github.com/Javen205/JPay OsChina:h ...

  2. Android版-支付宝APP支付

    此项目已开源 赶快来围观 Start支持下吧 [客户端开源地址-JPay][服务端端开源地址-在com.javen.alipay 包名下] 上一篇详细介绍了微信APP支付 点击这里 此篇文章来详细介绍 ...

  3. Android版-微信APP支付

    首发地址: Android版-微信APP支付 欢迎留言.转发 微信极速开发系列文章(微信支付.授权获取用户信息等):点击这里 目录 1.注册账号.开发者认证 2.添加应用 3.申请微信支付 4.技术开 ...

  4. 支付宝APP支付IOS手机端java后台版

    版权声明:http://blog.csdn.net/u012131769/article/details/76639527#t8 转载:http://blog.csdn.net/u012131769/ ...

  5. 支付宝APP支付后台参数生成Java版(一)

    一.支付参数组装: String[] parameters={ "service=\"mobile.securitypay.pay\"",//固定值 " ...

  6. 微信支付(公众号支付APIJS、app支付)服务端统一下单接口java版

    一.微信公众号支付APIJS: 要完整的实现微信支付功能,需要前后端一起实现,还需要微信商户平台的配置.这里只是涉及服务端的代码. jar包:pom.xml <!-- ↓↓↓↓↓↓↓↓ 支付相关 ...

  7. 支付宝 app支付 沙盘使用

    文档说明 沙箱测试: App支付沙箱接入注意点 1.app支付支持沙箱接入:在沙箱调通接口后,必须在线上进行测试与验收,所有返回码及业务逻辑以线上为准:2.app支付只支持余额支付,不支持银行卡.余额 ...

  8. 微信支付-微信公众号支付,微信H5支付,微信APP支付,微信扫码支付

    在支付前,如果使用第三方MVC框架,则使用重写模式,服务器也需要配置该项 if (!-e $request_filename){ rewrite ^/(.*)$ /index.php/$ last; ...

  9. APP支付 + 退款(JAVA实现)

    首先,你得先有微信开发平台账号密码还需要开通应用,然后还有微信服务商平台商户版账号(这些我都是给产品经理拿的) 其次我认为你先去看一看微信开发平台的文档!  https://pay.weixin.qq ...

随机推荐

  1. python3使用pymysql库连接MySQL的常用操作

    #导入pymysql模块import pymysql #连接数据库connect = pymysql.connect( host='localhost', port=3306, user='root' ...

  2. 记一次使用getRequestDispatcher遇到的坑。。响应页面出现新建下载任务

    getRequestDispatcher RequestDispatcher接口提供将请求转发送到另一个资源的功能,它可能是html,servlet或jsp等. 此接口也可用于包括另一资源的内容.它是 ...

  3. ENVI_REGISTER_DOIT( )函数

    Envi_Register_Doit()函数利用控制点为裸数据定义投影坐标.   当将裸数据转为等经纬度投影时(Geographic),控制点pts中的经度值没有负值,0E~180E~360E,西经不 ...

  4. zookeeper、solrcloud、rediscluster集群解决方案

        集群解决方案 课程目标 目标1:说出什么是集群以及与分布式的区别 目标2:能够搭建Zookeeper集群 目标3:能够搭建SolrCloud集群 目标4:能够搭建RedisCluster集群 ...

  5. java枚举变量反解析用法

    最近常常有一些项目需要给枚举设值一个int值,以及对int值进行反解析出枚举类型,代码如下: public enum MatchResultEnum { /** * 赢 */ WIN(0), /** ...

  6. Java好的的工具类:JSONResult

    package com.nxhfzx.gdshopping.entity; import java.util.List; import com.fasterxml.jackson.databind.J ...

  7. Programming Series 1.0 — C Programming

    In the growing world of technology, C programming has kind of lost its way. Today, we have a million ...

  8. DataTable行列转换

    #region DataTable行列转换 /// <summary> /// DataTable行列转换 /// </summary> /// <param name= ...

  9. mysql查询正在执行的sql

    mysql> SHOW VARIABLES LIKE "general_log%"; +------------------+------------------------ ...

  10. node note

    1.关于next() next()函数接受一个Error对象,在判断错误时,返回这个next()函数,并传入自定义的Error对象可以被向下捕捉,你也可以自定义统一捕捉错误Error的中间件,在app ...