using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using WebService.SDK.PayCommon;
namespace WebService.SDK.CCBPay
{
public class CCBPayAPI
{
///
/// 建设银行被扫交易接口
///
/// 接口配置
/// 平台商户信息
/// 用户付款授权码
/// 商户交易订单号
/// 交易金额(元)
///
public static Model.CCBPayResultModel ScanPay(CCBPayConfig payConfig,
MobilePayConfig.PayMerchant merchantInfo, string authCode,
string merchantOrderCode, string payAmount)
{
return ScanPay(payConfig, merchantInfo, authCode, merchantOrderCode, payAmount, null);
}
///
/// 建设银行被扫交易接口
///
/// 接口配置
/// 平台商户信息
/// 用户付款授权码
/// 商户交易订单号
/// 交易金额(元)
///
public static Model.CCBPayResultModel ScanPay(CCBPayConfig payConfig,
MobilePayConfig.PayMerchant merchantInfo, string authCode,
string merchantOrderCode, string payAmount, List goodsDetails)
{
if (payConfig == null)
{
return default(Model.CCBPayResultModel);
}
if (merchantInfo == null || string.IsNullOrWhiteSpace(merchantInfo.MerchantCode) ||
string.IsNullOrWhiteSpace(merchantInfo.MerchantKey) ||
string.IsNullOrWhiteSpace(merchantInfo.MerchantPosCode))
{
return default(Model.CCBPayResultModel);
}
if (!decimal.TryParse(payAmount, out decimal _PayAmount) || _PayAmount <= 0)
{
return default(Model.CCBPayResultModel);
}
Dictionary _ApiDictionary = new Dictionary
{
//{ "MERCHANTID", merchantInfo.MerchantCode },//平台商户号
//{ "POSID", merchantInfo.MerchantPosCode },//柜台号
//{ "BRANCHID", payConfig.Organization },//分行号
//{ "TERMNO1", "" },//终端编号1
//{ "TERMNO2", "" }, //终端编号2
{ "MERFLAG", "1" },//商户类型
{ "ORDERID", merchantOrderCode },//订单号
{ "QRCODE", authCode},//用户付款码
{ "AMOUNT", payAmount },//交易金额
{ "TXCODE", "PAY100" }//接口名称,固定:PAY100
};
if (goodsDetails != null)
{
for (int i = 0; i < goodsDetails.Count; i++)
{
goodsDetails[i].quantity = (int)goodsDetails[i].quantity;
goodsDetails[i].price = decimal.Parse(goodsDetails[i].price.ToString("F2"));
if (string.IsNullOrWhiteSpace(goodsDetails[i].goods_name))
{
goodsDetails[i].goods_name = goodsDetails[i].goods_id;
}
}
_ApiDictionary.Add("goods_detail_ali", JsonConvert.SerializeObject(goodsDetails));//支付宝优惠券商品参数
}
LogHelper.WriteReceiveLog("支付反扫-传第三方参数:" +
_ApiDictionary.Select(pair => pair.Key + "=" + pair.Value).
DefaultIfEmpty("").Aggregate((a, b) => a + "&" + b));
//测试用日志记录
LogHelper.WriteSendLog("支付调用的服务地址" + payConfig.ScanURL);
return JsonConvert.DeserializeObject(
CommonHelper.HttpUrlPost($"MERCHANTID={merchantInfo.MerchantCode}" +
$"&POSID={merchantInfo.MerchantPosCode}&BRANCHID={payConfig.Organization}" +
$"&ccbParam={ApiParamSign(_ApiDictionary, merchantInfo.MerchantKey)}",
payConfig.ScanURL, "application/x-www-form-urlencoded", payConfig.PlatformTimeout));
}
///
/// 建设银行交易查询接口
///
/// 接口配置
/// 平台商户信息
/// 商户交易订单号
/// 平台交易订单号
/// 交易金额
/// 累计查询次数
///
public static Model.CCBPayResultModel QueryPay(CCBPayConfig payConfig,
MobilePayConfig.PayMerchant merchantInfo, string merchantOrderCode,
string platformOrderCode, string payType, int queryCount)
{
if (payConfig == null)
{
return default(Model.CCBPayResultModel);
}
if (merchantInfo == null || string.IsNullOrWhiteSpace(merchantInfo.MerchantCode) ||
string.IsNullOrWhiteSpace(merchantInfo.MerchantKey) ||
string.IsNullOrWhiteSpace(merchantInfo.MerchantPosCode))
{
return default(Model.CCBPayResultModel);
}
int QRCodeType = 2;
switch (payType.ToUpper())
{
case "WECHAT":
QRCodeType = 2;
break;
case "ALIPAY":
QRCodeType = 3;
break;
case "UNIONPAY":
QRCodeType = 4;
break;
}
Dictionary _ApiDictionary = new Dictionary
{
//{ "MERCHANTID", merchantInfo.MerchantCode },//平台商户号
//{ "POSID", merchantInfo.MerchantPosCode },//柜台号
//{ "BRANCHID", payConfig.Organization },//分行号
//{ "TERMNO1", "" },//终端编号1
//{ "TERMNO2", "" }, //终端编号2
{ "MERFLAG", "1" },//商户类型
{ "ORDERID", merchantOrderCode },//订单号
{ "QRYTIME", queryCount.ToString() },//查询次数
{ "QRCODETYPE", QRCodeType.ToString() },//二维码类型
{ "TXCODE", "PAY101" }
};
LogHelper.WriteReceiveLog("支付查询-传第三方参数:" +
_ApiDictionary.Select(pair => pair.Key + "=" + pair.Value).
DefaultIfEmpty("").Aggregate((a, b) => a + "&" + b));
return JsonConvert.DeserializeObject(
CommonHelper.HttpUrlPost($"MERCHANTID={merchantInfo.MerchantCode}" +
$"&POSID={merchantInfo.MerchantPosCode}&BRANCHID={payConfig.Organization}" +
$"&ccbParam={ApiParamSign(_ApiDictionary, merchantInfo.MerchantKey)}",
payConfig.ScanURL, "application/x-www-form-urlencoded", payConfig.PlatformTimeout));
}
///
/// 建设银行交易退款接口
///
/// 接口配置
/// 平台商户信息
/// 平台交易订单号
/// 商户交易订单号
/// 退款订单号
/// 退款金额
///
public static Model.CCBRefundModel RefundPay(CCBPayConfig payConfig,
MobilePayConfig.PayMerchant merchantInfo, string platformOrderCode,
string merchantOrderCode, string refundOrderCode, string payAmount)
{
if (payConfig == null)
{
return default(Model.CCBRefundModel);
}
if (merchantInfo == null || string.IsNullOrWhiteSpace(merchantInfo.MerchantCode))
{
return default(Model.CCBRefundModel);
}
if (!decimal.TryParse(payAmount, out decimal _PayAmount) || _PayAmount <= 0)
{
return default(Model.CCBRefundModel);
}
Dictionary _ApiDictionary = new Dictionary
{
{ "CUST_ID", merchantInfo.MerchantCode },//建设银行平台商户号
{ "ORDER", merchantOrderCode },//原商户订单号
{ "MONEY", _PayAmount.ToString() } //退款款交易金额
};
string str_Refund = $"{merchantInfo.MerchantCode}&{merchantOrderCode}&{_PayAmount.ToString()}";
_ApiDictionary.Add("fundParams", Encry(str_Refund, "503252CD487D3B0ADA6CD0A42EF28CF8"));
LogHelper.WriteReceiveLog("支付退款-传第三方参数:" +
_ApiDictionary.Select(pair => pair.Key + "=" + pair.Value).
DefaultIfEmpty("").Aggregate((a, b) => a + "&" + b));
//测试用日志记录
LogHelper.WriteSendLog("退款调用的服务地址" + payConfig.PayRefundURL);
return JsonConvert.DeserializeObject(CommonHelper.HttpUrlPost(
$"fundParams={System.Web.HttpUtility.UrlEncode(Encry(str_Refund, "503252CD487D3B0ADA6CD0A42EF28CF8"))}",
payConfig.PayRefundURL, "application/x-www-form-urlencoded", payConfig.PlatformTimeout, Encoding.Default, false));
}
///
/// 建设银行支付平台参数签名
///
/// 待签名参数集
/// 签名密钥
///
private static string ApiParamSign(Dictionary signParm, string mchKey)
{
try
{
//拼接待签名参数字符串
string parameter = signParm.Select(pair => $"{pair.Key}={pair.Value}").
DefaultIfEmpty("").Aggregate((a, b) => $"{a}&{b}");
return new CCB_B2CPay_Util.CCBPayUtil().makeCCBParam(parameter, mchKey);
}
catch
{
return "";
}
}
///
/// 建设银行参数签名加密
///
/// 待加密字符串
/// 密钥
///
private static string CCBDESEncrypt(string encryptString, string sKey)
{
byte[] byKey = null;
byte[] IV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
try
{
byKey = Encoding.UTF8.GetBytes(sKey.Substring(0, 8));
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
des.Mode = CipherMode.ECB;
byte[] inputByteArray = Encoding.GetEncoding("utf-16be").GetBytes(encryptString);
MemoryStream ms = new MemoryStream();
// byte[] bytes = new byte[inputByteArray.Length + 2];
List bytes = new List();
bytes.Add(0xfe);
bytes.Add(0xff);
bytes.AddRange(inputByteArray.ToList());
CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(byKey, IV), CryptoStreamMode.Write);
cs.Write(bytes.ToArray(), 0, bytes.Count);
cs.FlushFinalBlock();
var resultStr = Convert.ToBase64String(ms.ToArray());
int count = resultStr.Length / 76;
count += resultStr.Length % 76 > 0 ? 1 : 0;
StringBuilder result = new StringBuilder();
for (int i = 0; i < count; i++)
{
if (resultStr.Length > (i + 1) * 76)
result.Append(resultStr.Substring(i * 76, 76) + Environment.NewLine);//此处不能撤销换行
else
result.Append(resultStr.Substring(i * 76, resultStr.Length - i * 76));
}
return result.ToString().Replace("+", ",");
}
catch (Exception ex)
{
throw ex;
}
}
/// AES加密
/// 明文
/// 密钥,长度为16的字符串 s
/// 密文
public static string Encry(string text, string key)
{
string iv = key;
if (key.Length > 16)
{
// IV为商户MD5密钥后16位
iv = key.Substring(key.Length - 16);
// RES的KEY 为商户MD5密钥的前16位
key = key.Substring(0, 16);
}
return EncodeAES(text, key, iv);
}
/// AES加密
/// 明文
/// 密钥,长度为16的字符串
/// 偏移量,长度为16的字符串
/// 密文
public static string EncodeAES(string text, string key, string iv)
{
RijndaelManaged rijndaelCipher = new RijndaelManaged();
rijndaelCipher.Mode = CipherMode.CBC;
rijndaelCipher.Padding = PaddingMode.PKCS7;
rijndaelCipher.KeySize = 128;
rijndaelCipher.BlockSize = 128;
byte[] pwdBytes = System.Text.Encoding.UTF8.GetBytes(key);
byte[] keyBytes = new byte[16];
int len = pwdBytes.Length;
if (len > keyBytes.Length)
len = keyBytes.Length;
System.Array.Copy(pwdBytes, keyBytes, len);
rijndaelCipher.Key = keyBytes;
rijndaelCipher.IV = Encoding.UTF8.GetBytes(iv);
ICryptoTransform transform = rijndaelCipher.CreateEncryptor();
byte[] plainText = Encoding.UTF8.GetBytes(text);
byte[] cipherBytes = transform.TransformFinalBlock(plainText, 0, plainText.Length);
return Convert.ToBase64String(cipherBytes);
}
/// AES解密
/// 密文
/// 密钥,长度为16的字符串
/// 偏移量,长度为16的字符串
/// 明文
public static string DecodeAES(string text, string key, string iv)
{
RijndaelManaged rijndaelCipher = new RijndaelManaged();
rijndaelCipher.Mode = CipherMode.CBC;
rijndaelCipher.Padding = PaddingMode.PKCS7;
rijndaelCipher.KeySize = 128;
rijndaelCipher.BlockSize = 128;
byte[] encryptedData = Convert.FromBase64String(text);
byte[] pwdBytes = System.Text.Encoding.UTF8.GetBytes(key);
byte[] keyBytes = new byte[16];
int len = pwdBytes.Length;
if (len > keyBytes.Length)
len = keyBytes.Length;
System.Array.Copy(pwdBytes, keyBytes, len);
rijndaelCipher.Key = keyBytes;
rijndaelCipher.IV = Encoding.UTF8.GetBytes(iv);
ICryptoTransform transform = rijndaelCipher.CreateDecryptor();
byte[] plainText = transform.TransformFinalBlock(encryptedData, 0, encryptedData.Length);
return Encoding.UTF8.GetString(plainText);
}
}
}