对银联支付的二次封装,支持pc端
类图
pay(pc):
var title = "银联支付";
var orderNo = ""; //订单号
var tradeMoney = 0.00;
var notifyUrl = "host/NotifyCallback.aspx";
var returnUrl = "host/ReturnUrl.aspx";
var key = ""; //账户的key
var partner = ""; //账户的partnerid
var chairtyName = ""; //账户显示名称
var unionPay = new UnionPay.Submit(key, partner, chairtyName));
unionPay.Pay(title, orderNo, tradeMoney, notifyUrl, returnUrl);
return(pc):
public partial class NotifyUrl : UnionPay.NotifyPage
{
protected override void OnNotifyConfirm()
{
//todo:业务逻辑处理
}
}
Submit.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Web;
using com.unionpay.upop.sdk;
namespace UnionPay
{
public class Submit
{
/// <summary>
/// 实例化,默认UinonPay.config
/// </summary>
public Submit()
{
UPOPSrv.LoadConf(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "UinonPay.config"));
}
/// <summary>
/// 实例化
/// </summary>
/// <param name="configPath">配置文件全路径</param>
public Submit(string configPath)
{
UPOPSrv.LoadConf(configPath);
}
/// <summary>
/// 实例化
/// </summary>
/// <param name="key">key</param>
/// <param name="partner">partnetid</param>
/// <param name="chairtyName">账户名称</param>
public Submit(string key, string partner, string chairtyName)
{
var stream = new Config().SetConfig(key, partner, chairtyName);
UPOPSrv.LoadConf(stream);
}
public void Pay(string title, string orderNo, decimal tradeMoney, string notifyUrl, string returnUrl)
{
var param = new Dictionary<string, string>
{
{"transType", UPOPSrv.TransType.CONSUME}, //交易类型,前台只支持CONSUME 和PRE_AUTH
{"commodityUrl", ""}, //商品URL
{"commodityName", title}, //商品名称
{"commodityUnitPrice", "1"}, //商品单价,分为单位
{"commodityQuantity", "1"}, //商品数量
{"orderNumber", orderNo}, //订单号
{"orderAmount", (tradeMoney * 100).ToString().Split('.')[0]}, //交易金额
{"orderCurrency", UPOPSrv.CURRENCY_CNY}, //币种
{"orderTime", DateTime.Now.ToString("yyyyMMddHHmmss")}, //交易时间
{"customerIp", HttpContext.Current.Request.UserHostAddress}, //用户IP
{"frontEndUrl", notifyUrl}, //前台回调URL
{"backEndUrl", returnUrl} //后台回调URL(前台请求时可为空)
};
var srv = new FrontPaySrv(param);
HttpContext.Current.Response.Write(srv.CreateHtml());
}
}
}
Config.cs
using System.IO;
using System.Xml;
namespace UnionPay
{
public class Config
{
private static XmlDocument _xmlDoc;
/// <summary>
/// xml模板
/// </summary>
private static XmlDocument XmlDoc
{
get
{
if (_xmlDoc == null)
{
_xmlDoc = new XmlDocument();
_xmlDoc.Load("Template.config");
}
return _xmlDoc;
}
}
public Stream SetConfig(string key, string partner, string chairtyName)
{
var ConfigInf = XmlDoc.SelectSingleNode("ConfigInf");
var securityKey = ConfigInf.SelectSingleNode("securityKey");
securityKey.InnerText = key;
var payParamsPredef = ConfigInf.SelectSingleNode("payParamsPredef");
var merId = payParamsPredef.SelectSingleNode("merId");
merId.InnerText = partner;
var merAbbr = payParamsPredef.SelectSingleNode("merAbbr");
merAbbr.InnerText = chairtyName;
var bytes = System.Text.Encoding.UTF8.GetBytes(XmlDoc.InnerXml);
var stream = new MemoryStream(bytes);
return stream;
}
}
}
Template.config
<?xml version="1.0"?>
<ConfigInf xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<signMethod>MD5</signMethod>
<securityKey>{$key}</securityKey>
<frontPayURL>https://unionpaysecure.com/api/Pay.action</frontPayURL>
<backPayURL>https://unionpaysecure.com/api/BSPay.action</backPayURL>
<queryURL>https://unionpaysecure.com/api/Query.action</queryURL>
<SSLCertPolicy>Ignore</SSLCertPolicy>
<payParamsPredef>
<version>1.0.0</version>
<charset>UTF-8</charset>
<merId>{$merId}</merId>
<acqCode></acqCode>
<merCode></merCode>
<merAbbr>{$name}</merAbbr>
</payParamsPredef>
<payParams>
<string>version</string>
<string>charset</string>
<string>transType</string>
<string>origQid</string>
<string>merId</string>
<string>merAbbr</string>
<string>acqCode</string>
<string>merCode</string>
<string>commodityUrl</string>
<string>commodityName</string>
<string>commodityUnitPrice</string>
<string>commodityQuantity</string>
<string>commodityDiscount</string>
<string>transferFee</string>
<string>orderNumber</string>
<string>orderAmount</string>
<string>orderCurrency</string>
<string>orderTime</string>
<string>customerIp</string>
<string>customerName</string>
<string>defaultPayType</string>
<string>defaultBankNumber</string>
<string>transTimeout</string>
<string>frontEndUrl</string>
<string>backEndUrl</string>
<string>merReserved</string>
</payParams>
<payParamsNotEmpty>
<string>version</string>
<string>charset</string>
<string>transType</string>
<string>merId</string>
<string>merAbbr</string>
<string>orderNumber</string>
<string>orderAmount</string>
<string>orderCurrency</string>
<string>orderTime</string>
<string>customerIp</string>
<string>frontEndUrl</string>
<string>backEndUrl</string>
</payParamsNotEmpty>
<queryParams>
<string>version</string>
<string>charset</string>
<string>transType</string>
<string>merId</string>
<string>orderNumber</string>
<string>orderTime</string>
<string>merReserved</string>
</queryParams>
<merReservedParams>
<!-- NEW NAME OLD NAME -->
<string>cardNumber</string>
<string>pan</string>
<string>cardPasswd</string>
<string>password</string>
<string>credentialType</string>
<string>idType</string>
<string>cardCvn2</string>
<string>cvn</string>
<string>cardExpire</string>
<string>expire</string>
<string>credentialNumber</string>
<string>idNo</string>
<string>credentialName</string>
<string>name</string>
<string>phoneNumber</string>
<string>mobile</string>
<string>merAbstract</string>
<!-- tdb only -->
<string>orderTimeoutDate</string>
<string>origOrderNumber</string>
<string>origOrderTime</string>
</merReservedParams>
</ConfigInf>
NotifyPage.cs
using System;
using System.Globalization;
using System.IO;
using System.Text;
namespace UnionPay
{
public abstract class NotifyPage : System.Web.UI.Page
{
/// <summary>
/// 商户订单号
/// </summary>
protected string OrderNo { get; private set; }
/// <summary>
/// 交易金额
/// </summary>
protected decimal TradeMoney { get; private set; }
/// <summary>
/// 交易状态
/// </summary>
protected string TradeStatus { get; private set; }
/// <summary>
/// 业务逻辑处理
/// </summary>
protected abstract void OnNotifyConfirm();
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack) return;
OrderNo = Request.Form["orderNumber"];
TradeMoney = Convert.ToDecimal(Request.Form["orderAmount"]);
TradeStatus = Request.Form["respCode"];
if (TradeStatus == "00")
{
OnNotifyConfirm();
Response.Write("200");
}
Response.End();
}
/// <summary>
/// 写日志
/// </summary>
protected void WriteLog(string text, string logType)
{
var strPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "/log/UnionPay/");
var dateFloderName = DateTime.Now.ToString("yyyyMM");
strPath = string.Format("{0}/{1}", strPath, dateFloderName);
if (!Directory.Exists(strPath)) Directory.CreateDirectory(strPath);
strPath = strPath + "\\" + DateTime.Now.ToString("yyyyMMddHHmmssffff", DateTimeFormatInfo.InvariantInfo) + ".txt";
var fs = new StreamWriter(strPath, true, Encoding.Default);
fs.Write(text);
fs.Close();
}
}
}