|
|
|
|
using POSV.Proxy.Common;
|
|
|
|
|
using POSV.Proxy.Tool;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
|
|
|
|
namespace POSV.Proxy.MIS
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
public class SoftPosPay
|
|
|
|
|
{
|
|
|
|
|
InIHelper _ini = null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[DllImport("softpos.dll")]
|
|
|
|
|
private static extern int CreditTrans(byte[] strin, byte[] strout);
|
|
|
|
|
|
|
|
|
|
public SoftPosPay()
|
|
|
|
|
{
|
|
|
|
|
_ini = new InIHelper(System.AppDomain.CurrentDomain.BaseDirectory + "\\trans.ini");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 修改连接地址、端口
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public ReturnInfo<bool> SetTransIniIp(string _ip, string _port)
|
|
|
|
|
{
|
|
|
|
|
ReturnInfo<bool> returnInfo = new ReturnInfo<bool>();
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
//服务器地址
|
|
|
|
|
_ini.WriteContentValue("PARAMETER ASSIGN", "IP_ADDRESS", _ip);
|
|
|
|
|
|
|
|
|
|
//服务器端口
|
|
|
|
|
_ini.WriteContentValue("PARAMETER ASSIGN", "IP_PORT", _port);
|
|
|
|
|
|
|
|
|
|
//通讯方式 NO_NET 为脱机测试模式 TCPIP 为网络模式
|
|
|
|
|
_ini.WriteContentValue("PARAMETER ASSIGN", "NET_MODE", "NO_NET");
|
|
|
|
|
|
|
|
|
|
returnInfo.Code = ReturnState.Succeed;
|
|
|
|
|
|
|
|
|
|
return returnInfo;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
returnInfo.ErrorMessage = ex.Message;
|
|
|
|
|
return returnInfo;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public ReturnInfo<string[]> GetransIniIp()
|
|
|
|
|
{
|
|
|
|
|
ReturnInfo<string[]> returnInfo = new ReturnInfo<string[]>();
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
string[] ip_port = new string[2];
|
|
|
|
|
|
|
|
|
|
//服务器地址
|
|
|
|
|
ip_port[0] = _ini.ReadContentValue("PARAMETER ASSIGN", "IP_ADDRESS");
|
|
|
|
|
|
|
|
|
|
//服务器端口
|
|
|
|
|
ip_port[1] = _ini.ReadContentValue("PARAMETER ASSIGN", "IP_PORT");
|
|
|
|
|
|
|
|
|
|
returnInfo.Code = ReturnState.Succeed;
|
|
|
|
|
returnInfo.Data = ip_port;
|
|
|
|
|
return returnInfo;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
returnInfo.ErrorMessage = ex.Message;
|
|
|
|
|
return returnInfo;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 发起支付
|
|
|
|
|
/// </summary>
|
|
|
|
|
public ReturnInfo<ReturnData> InitiateConsumption(RequestData _request)
|
|
|
|
|
{
|
|
|
|
|
ReturnInfo<ReturnData> returnInfo = new ReturnInfo<ReturnData>();
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var _strin = Encoding.ASCII.GetBytes(_request.ToRequestString());
|
|
|
|
|
var _strout = new byte[1024];
|
|
|
|
|
|
|
|
|
|
CreditTrans(_strin, _strout);
|
|
|
|
|
|
|
|
|
|
ReturnData _data = new ReturnData();
|
|
|
|
|
|
|
|
|
|
_data.Data = Encoding.ASCII.GetString(_strout);
|
|
|
|
|
_data.InitializeData();
|
|
|
|
|
|
|
|
|
|
if (_data.Code.Equals("00"))
|
|
|
|
|
{
|
|
|
|
|
returnInfo.Code = ReturnState.Succeed;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
returnInfo.Code = ReturnState.Failed;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
returnInfo.Data = _data;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return returnInfo;
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
returnInfo.ErrorMessage = ex.Message;
|
|
|
|
|
return returnInfo;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 请求支付参数
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class RequestData
|
|
|
|
|
{
|
|
|
|
|
private string _PosNo = "";
|
|
|
|
|
private string _OperatorNo = "";
|
|
|
|
|
private string _ContentType = "";
|
|
|
|
|
private string _PayAmount = "";
|
|
|
|
|
private string _payType = "";
|
|
|
|
|
private string _Outtrading = "";
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// POS号
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string PosNo
|
|
|
|
|
{
|
|
|
|
|
get => _PosNo;
|
|
|
|
|
set => _PosNo = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 操作员
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string OperatorNo
|
|
|
|
|
{
|
|
|
|
|
get => _OperatorNo;
|
|
|
|
|
set => _OperatorNo = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 交易类型标志 ‘
|
|
|
|
|
/// 为 C,表示是正数( 消费交易);
|
|
|
|
|
/// 为 I,表示是正数( 查询余额交易);
|
|
|
|
|
/// 为 D,表示是负数( 取消交易);
|
|
|
|
|
/// 为 R,表示是负数( 退货交易);
|
|
|
|
|
/// 为 0[零],表示( 结帐、交易一览和重打票据),
|
|
|
|
|
/// 将出现菜单界面选择类型,如 I 接口不做,也可在此实现。
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string ContentType
|
|
|
|
|
{
|
|
|
|
|
get => _ContentType;
|
|
|
|
|
set => _ContentType = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 总金额
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string PayAmount
|
|
|
|
|
{
|
|
|
|
|
get => _PayAmount;
|
|
|
|
|
set => _PayAmount = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 支付方式
|
|
|
|
|
/// 001 选择用卡 (记账类型:银行卡)
|
|
|
|
|
/// 002 选择银联二维码扫码(记账类型:银行卡)
|
|
|
|
|
/// 003 选择支付宝扫码(记账类型:支付宝)
|
|
|
|
|
/// 004 选择微信扫码(记账类型:微信)
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string PayType
|
|
|
|
|
{
|
|
|
|
|
get => _payType;
|
|
|
|
|
set => _payType = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 原交易要素
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Outtrading
|
|
|
|
|
{
|
|
|
|
|
get => _Outtrading;
|
|
|
|
|
set => _Outtrading = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 请求逻辑,有疑问请查阅文档
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public string ToRequestString()
|
|
|
|
|
{
|
|
|
|
|
string _str = "";
|
|
|
|
|
_str += _PosNo.PadRight(10, ' ');
|
|
|
|
|
_str += _OperatorNo.PadRight(10, ' ');
|
|
|
|
|
_str += _ContentType;
|
|
|
|
|
_str += _PayAmount.PadLeft(12, '0');
|
|
|
|
|
_str += _payType;
|
|
|
|
|
_str += _Outtrading.PadRight(96,' ');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return _str;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 返回数据
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class ReturnData
|
|
|
|
|
{
|
|
|
|
|
private string _Data;
|
|
|
|
|
|
|
|
|
|
private string _Code = "";
|
|
|
|
|
private string _CardNo = "";
|
|
|
|
|
private string _ContentType = "";
|
|
|
|
|
private string _PayAmount = "";
|
|
|
|
|
private string _SerialCode = "";
|
|
|
|
|
private string _BankbkNo = "";
|
|
|
|
|
private string _ReferenceNo = "";
|
|
|
|
|
private string _AuthorizationCode = "";
|
|
|
|
|
private string _BatchNo = "";
|
|
|
|
|
private string _TerminalNo = "";
|
|
|
|
|
private string _TenantNo = "";
|
|
|
|
|
private string _PayDate = "";
|
|
|
|
|
private string _PayTime = "";
|
|
|
|
|
private string _PayCatdNo = "";
|
|
|
|
|
private string _TradeNo = "";
|
|
|
|
|
private string _ActualPayAmount = "";
|
|
|
|
|
private string _Discounts = "";
|
|
|
|
|
private string _Outtrading = "";
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 响应码
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Code { get => _Code; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 卡号
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string CardNo { get => _CardNo; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 交易类型标志
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string ContentType { get => _ContentType; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 总金额
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string PayAmount { get => _PayAmount; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 交易流水号
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string SerialCode { get => _SerialCode; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 发卡行号
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string BankbkNo { get => _BankbkNo; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 参考号
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string ReferenceNo { get => _ReferenceNo; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 授权码
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string AuthorizationCode { get => _AuthorizationCode; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 批次号
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string BatchNo { get => _BatchNo; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 终端号
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string TerminalNo { get => _TerminalNo; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 商户号
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string TenantNo { get => _TenantNo; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 交易日期
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string PayDate { get => _PayDate; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 交易时间
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string PayTime { get => _PayTime; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 借贷记卡标识
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string PayCatdNo { get => _PayCatdNo; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 渠道订单号
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string TradeNo { get => _TradeNo; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 实际支付金额
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string ActualPayAmount { get => _ActualPayAmount; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 优惠金额
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Discounts { get => _Discounts; }
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 交易要素
|
|
|
|
|
/// </summary>
|
|
|
|
|
public string Outtrading { get => _Outtrading; }
|
|
|
|
|
|
|
|
|
|
public string Data
|
|
|
|
|
{
|
|
|
|
|
get
|
|
|
|
|
{
|
|
|
|
|
return this._Data;
|
|
|
|
|
}
|
|
|
|
|
set
|
|
|
|
|
{
|
|
|
|
|
this._Data = value;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 根据文档解析数据
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void InitializeData()
|
|
|
|
|
{
|
|
|
|
|
var _len = 0;
|
|
|
|
|
this._Code = this._Data.Substring(_len , 2).Trim();
|
|
|
|
|
_len = _len + 2;
|
|
|
|
|
this._CardNo = this.Data.Substring(_len, 19).Trim();
|
|
|
|
|
_len = _len + 19;
|
|
|
|
|
this._ContentType = this.Data.Substring(_len, 1).Trim();
|
|
|
|
|
_len = _len + 1;
|
|
|
|
|
this._PayAmount = this.Data.Substring(_len, 12).Trim();
|
|
|
|
|
_len = _len + 12;
|
|
|
|
|
this._SerialCode = this.Data.Substring(_len, 6).Trim();
|
|
|
|
|
_len = _len + 6;
|
|
|
|
|
this._BankbkNo = this.Data.Substring(_len, 3).Trim();
|
|
|
|
|
_len = _len + 3;
|
|
|
|
|
this._ReferenceNo = this.Data.Substring(_len, 12).Trim();
|
|
|
|
|
_len = _len + 12;
|
|
|
|
|
this._AuthorizationCode = this.Data.Substring(_len, 6).Trim();
|
|
|
|
|
_len = _len + 6;
|
|
|
|
|
this._BatchNo = this.Data.Substring(_len, 6).Trim();
|
|
|
|
|
_len = _len + 6;
|
|
|
|
|
this._TerminalNo = this.Data.Substring(_len, 8).Trim();
|
|
|
|
|
_len = _len + 8;
|
|
|
|
|
this._TenantNo = this.Data.Substring(_len, 15).Trim();
|
|
|
|
|
_len = _len + 15;
|
|
|
|
|
this._PayDate = this.Data.Substring(_len, 4).Trim();
|
|
|
|
|
_len = _len + 4;
|
|
|
|
|
this._PayTime = this.Data.Substring(_len, 6).Trim();
|
|
|
|
|
_len = _len + 6;
|
|
|
|
|
this._PayCatdNo = this.Data.Substring(_len, 3).Trim();
|
|
|
|
|
_len = _len + 3;
|
|
|
|
|
this._TradeNo = this.Data.Substring(_len, 64).Trim();
|
|
|
|
|
_len = _len + 64;
|
|
|
|
|
this._ActualPayAmount = this.Data.Substring(_len, 12).Trim();
|
|
|
|
|
_len = _len + 12;
|
|
|
|
|
this._Discounts = this.Data.Substring(_len, 12).Trim();
|
|
|
|
|
_len = _len + 12;
|
|
|
|
|
this._Outtrading = this.Data.Substring(_len, 96).Trim();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|