PayDemo
介绍
Windows应用软件,支付示例。(开发环境 Microsoft Visual Studio,编程语言C#)
1、支付插件引入
添加PayTool.cs至你的项目中
2、支付接入
示例demo: http://scimence.cn/src/PayDemo/PayDemo.exe
示例源码: http://scimence.cn/src/PayDemo/PayDemo_20210530.zip
附录:
PayTool.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace PayDemo
{
// http://scimence.cn:8003/url/QRPay.html 开发者账号注册时,设置您的开发者名称
// 添加PayTool.cs类到项目,为应用提供支付功能
// 1、初始化,软件名称自定义,scimence修改为您自己的支付宝收款账号, 在PayResult中执行回调处理逻辑
// PayTool.Init("PayDemo", "scimence", PayResult);
// 2、调用支付
// PayTool.Pay("商品1", "0.01", "00001", "reserve");
/// <summary>
/// 支付插件
/// </summary>
public class PayTool
{
public static string ServerAddress = "www.scimence.cn:8003";
/// <summary>
/// 调用assembly中的静态方法
/// </summary>
private static object RunStatic(Assembly assembly, string classFullName, string methodName, object[] args)
{
if (assembly == null) return null;
Type type = assembly.GetType(classFullName, true, true);
//object[] arg = new object[] { "参数1", "参数2" };
object tmp = type.InvokeMember(methodName, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, args);
return tmp;
}
private static Assembly asm = null;
/// <summary>
/// 初始化
/// </summary>
/// <param name="softName">软件名称</param>
/// <param name="authorName">软件作者</param>
/// <param name="call">支付回调处理逻辑</param>
public static void Init(string softName, string authorName, FunCallBack call)
{
if (asm == null)
{
asm = Assembly.Load(GetByte());
}
if(asm != null)
{
thisCall = call;
Delegate deleg = NewDelegate(asm);
object[] args = new object[] { softName, authorName, deleg };
RunStatic(asm, "SciPay.PayTool", "Init", args);
}
}
/// <summary>
/// 调用支付
/// </summary>
/// <param name="productName">商品名称</param>
/// <param name="moneyYuan">支付金额元</param>
/// <param name="orderId">自定义订单号</param>
/// <param name="reserve">自定义预留字段</param>
public static void Pay(string productName, string moneyYuan, string orderId, string reserve)
{
if (asm != null)
{
object[] args = new object[] { productName, moneyYuan, orderId, reserve };
RunStatic(asm, "SciPay.PayTool", "Pay", args);
}
}
public delegate void FunCallBack(string productName, string moneyYuan, string orderId, string reserve);
private static FunCallBack thisCall = null;
public static void MethodF(string productName, string moneyYuan, string orderId, string reserve)
{
if (thisCall != null) thisCall(productName, moneyYuan, orderId, reserve);
}
/// <summary>
/// 构建assembly中申明的Delegate对象
/// </summary>
private static Delegate NewDelegate(Assembly assembly)
{
string name = Assembly.GetCallingAssembly().GetName().Name; // 获取当前程序集名称 PayDemo
Type methodF = Assembly.GetCallingAssembly().GetType(name + ".PayTool", true, true); // PayDemo.PayTool类
MethodInfo info = methodF.GetMethod("MethodF"); // 获取方法MethodF
// 使用当前类的Method函数创建一个deleget,用于接收dll执行回调
Type typeCall = assembly.GetType("SciPay.PayTool+FunCallBack", true, true);
Delegate d = Delegate.CreateDelegate(typeCall, info);
return d;
}
#region 支付插件
public static byte[] GetByte()
{
string data_run = getData("http://" + ServerAddress + "/src/scitools/DATA/SciPay.data");
byte[] bytes = ToBytes(data_run);
return bytes;
}
/// <summary>
/// 解析字符串为Bytes数组
/// </summary>
private static byte[] ToBytes(string data)
{
data = restore(data);
byte[] B = new byte[data.Length / 2];
char[] C = data.ToCharArray();
for (int i = 0; i < C.Length; i += 2)
{
byte b = ToByte(C[i], C[i + 1]);
B[i / 2] = b;
}
return B;
}
/// <summary>
/// 每两个字母还原为一个字节
/// </summary>
private static byte ToByte(char a1, char a2)
{
return (byte)((a1 - 'a') * 16 + (a2 - 'a'));
}
/// <summary>
/// 从指定dataUrl载入数据,并在本地缓存
/// </summary>
/// <param name="dataUrl"></param>
/// <returns></returns>
private static string getData(string dataUrl)
{
string data = "";
try
{
string fileName = dataUrl.Substring(dataUrl.LastIndexOf("/") + 1);
string localPath = AppDomain.CurrentDomain.BaseDirectory + fileName;
// 优先从本地载入数据
if (File.Exists(localPath))
{
long lastModify = new FileInfo(localPath).LastWriteTime.Ticks;
long secondSpace = (DateTime.Now.Ticks - lastModify) / 10000000;
if (secondSpace > 86400 * 1) // 超出1天,删除缓存文件
{
File.Delete(localPath);
}
else
{
data = File.ReadAllText(localPath).Trim();
if (data.Trim().Equals("")) File.Delete(localPath);
}
}
// 若本地无数据,则从网址加载
if (!File.Exists(localPath))
{
System.Net.WebClient client = new System.Net.WebClient();
data = client.DownloadString(dataUrl).Trim();
File.WriteAllText(localPath, data); // 本地缓存
}
}
catch (Exception) { }
return data;
}
/// <summary>
/// 还原为原有串信息
/// "enfkja4da6p4a4lia14ea11" ->
/// "enfkjaaaadaaaaaaaeaaaaaappppaaaaliaaaaaaaaaaaaaaeaaaaaaaaaaa"
/// </summary>
/// <param name="shrinkStr"></param>
/// <returns></returns>
public static string restore(string shrinkStr)
{
char C = ' ';
StringBuilder builder = new StringBuilder();
string numStr = "";
foreach (char c in shrinkStr)
{
if ('a' <= c && c <= 'z')
{
if (!numStr.Equals(""))
{
int n = Int32.Parse(numStr);
while (n-- > 1) builder.Append(C.ToString());
numStr = "";
}
builder.Append(c.ToString());
C = c;
}
else if ('0' <= c && c <= '9')
{
numStr += c.ToString();
}
}
if ('a' <= C && C <= 'z')
{
if (!numStr.Equals(""))
{
int n = Int32.Parse(numStr);
while (n-- > 1) builder.Append(C.ToString());
numStr = "";
}
}
return builder.ToString();
}
#endregion
}
}