环境
.net 6
AlipaySDKNet.OpenAPI 2.4.0
申请证书
登录支付宝开放平台https://open.alipay.com/
进入控制台
授权回调地址也设置一下,加密方式AES
新建.net 6空白的web项目
证书除了java都需要自己生成一下pkcs1的密钥
privatekey.txt就是根据应用私钥生成的pkcs1密钥
安装AlipaySDKNet.OpenAPI 2.4.0
配置json
"AliPayConfig": {"ServerUrl": "https://openapi.alipay.com","AppId": "",//参考appCertPublicKey_{APPID}.crt"PrivateKey": "AliPay/privatekey.txt","AlipayPublicKey": "AliPay/publickey.txt","AppCertPath": "AliPay/appCertPublicKey_{APPID}.crt","AlipayPublicCertPath": "AliPay/alipayCertPublicKey_RSA2.crt","RootCertPath": "AliPay/alipayRootCert.crt","EncryptKey": "","QrcodeNotifyUrl": "https://xxxx/Notify"
}
新建AliPayConfigModel.cs
namespace 支付宝转账测试01.Model
{/// <summary>/// 支付宝支付配置/// </summary>public class AliPayConfigModel{/// <summary>/// 服务器地址/// v2 https://openapi.alipay.com/gateway.do/// v3 https://openapi.alipay.com/// 【必填】/// </summary>public string ServerUrl { get; set; } = "";/// <summary>/// 应用ID/// 【必填】/// </summary>public string AppId { get; set; } = "";/// <summary>/// 应用密钥/// 【必填】/// </summary>public string PrivateKey { get; set; } = "";/// <summary>/// 支付宝公钥/// 【密钥模式】/// 【特殊必填,密钥模式和证书模式二选一,建议证书模式】/// </summary>public string AlipayPublicKey { get; set; } = "";/// <summary>/// 应用公钥/// 【证书模式】/// 【特殊必填,密钥模式和证书模式二选一,建议证书模式】/// </summary>public string AppCertPath { get; set; } = "";/// <summary>/// 支付宝公钥/// 【证书模式】/// 【特殊必填,密钥模式和证书模式二选一,建议证书模式】/// </summary>public string AlipayPublicCertPath { get; set; } = "";/// <summary>/// 支付宝根证书/// 【证书模式】/// 【特殊必填,密钥模式和证书模式二选一,建议证书模式】/// </summary>public string RootCertPath { get; set; } = "";/// <summary>/// AES加密的密钥/// 【选填】/// </summary>public string EncryptKey { get; set; } = "";/// <summary>/// 支付宝二维码扫码成功之后通知地址/// </summary>public string QrcodeNotifyUrl { get; set; } = "";}
}
实现方法
using AlipaySDKNet.OpenAPI.Api;
using AlipaySDKNet.OpenAPI.Client;
using AlipaySDKNet.OpenAPI.Model;
using AlipaySDKNet.OpenAPI.Util;
using AlipaySDKNet.OpenAPI.Util.Model;
using 支付宝转账测试01.Model;namespace ZhifubaoTest01
{public class Program{public static void Main(string[] args){var builder = WebApplication.CreateBuilder(args);var configuration = builder.Configuration;#region 配置阿里云var alipayConfigModel = configuration.GetSection("AliPayConfig").Get<AliPayConfigModel>();AlipayConfig alipayConfig = new AlipayConfig();// 设置应用私钥alipayConfig.PrivateKey = File.ReadAllText(alipayConfigModel.PrivateKey);alipayConfig.ServerUrl = alipayConfigModel.ServerUrl;alipayConfig.AppId = alipayConfigModel.AppId;//证书模式alipayConfig.AppCertPath = alipayConfigModel.AppCertPath;alipayConfig.AlipayPublicCertPath = alipayConfigModel.AlipayPublicCertPath;alipayConfig.RootCertPath = alipayConfigModel.RootCertPath;AlipayConfigUtil alipayConfigUtil = new AlipayConfigUtil(alipayConfig);#endregionvar app = builder.Build();app.MapGet("/", async (context) =>{AlipayFundAccountApi instance = new AlipayFundAccountApi();instance.Client.SetAlipayConfigUtil(alipayConfigUtil);string merchantUserId = null;string alipayUserId = "";//就是支付宝里面的商户号string alipayOpenId = null;string accountProductCode = null;string accountType = "ACCTRANS_ACCOUNT";string accountSceneCode = null;string extInfo = null;try{var response = instance.Query(merchantUserId, alipayUserId, alipayOpenId, accountProductCode, accountType, accountSceneCode, extInfo);await context.Response.WriteAsync($"xxx公司支付宝,账户可用余额:{response.AvailableAmount},账户冻结余额:{response.FreezeAmount}");}catch (ApiException e){AlipayFundAccountQueryDefaultResponse errorObject = (AlipayFundAccountQueryDefaultResponse)e.ErrorObject;await context.Response.WriteAsync("调用失败:" + errorObject);}});app.MapGet("/zhuanzhang", async (context) =>{AlipayFundTransUniApi instance = new AlipayFundTransUniApi();instance.Client.SetAlipayConfigUtil(alipayConfigUtil);AlipayFundTransUniTransferModel data = new AlipayFundTransUniTransferModel();data.OutBizNo = "202312131557";data.Remark = "";//业务备注长度200data.BusinessParams = "{\"payer_show_name_use_alias\":\"true\"}";data.BizScene = "DIRECT_TRANSFER";//单笔无密转账固定data.ProductCode = "TRANS_ACCOUNT_NO_PWD";//单笔无密转账固定Participant payeeInfo = new Participant();payeeInfo.Identity = "支付宝账号邮箱或者手机号";payeeInfo.IdentityType = "ALIPAY_LOGON_ID";payeeInfo.Name = "转账支付宝真实姓名";data.PayeeInfo = payeeInfo;data.TransAmount = "0.10";//单位是元,最低0.10data.OrderTitle = "xxx转账";//长度128try{var response = instance.Transfer(data);await context.Response.WriteAsync("转账完成");}catch (ApiException e){//{"code":"EXCEED_LIMIT_SM_MIN_AMOUNT","message":"请求金额不能低于0.1元"}var errStr = e.ErrorContent.ToString();var systemError = errStr?.Contains("SYSTEM_ERROR");//系统错误,需要单独处理var notEnough = errStr?.Contains("BALANCE_IS_NOT_ENOUGH");//余额不足var isNotRealName = errStr?.Contains("PAYEE_NOT_RELNAME_CERTIFY");//未实名认证var accOcupied = errStr?.Contains("PAYEE_ACC_OCUPIED");//多个支付宝账号var nameError = errStr?.Contains("PAYEE_NOT_EXIST");//收款方姓名错误if (systemError == true){/*可能发生了网络或者系统异常,导致无法判定准确的转账结果。此时,商户不能直接当做转账成功或者失败处理,可以考虑采用相同的out_biz_no重发请求,或者通过调用“(alipay.fund.trans.common.query 转账业务单据查询接口)”来查询该笔转账订单的最终状态*/AlipayFundTransCommonApi alipayFundTransInstance = new AlipayFundTransCommonApi();alipayFundTransInstance.Client.SetAlipayConfigUtil(alipayConfigUtil);string productCode = "STD_RED_PACKET";string bizScene = "PERSONAL_PAY";string outBizNo = "201808080001";string orderId = "20190801110070000006380000250621";string payFundOrderId = "20190801110070001506380000251556";try{var response = alipayFundTransInstance.Query(productCode, bizScene, outBizNo, orderId, payFundOrderId);}catch (ApiException ex){AlipayFundTransCommonQueryDefaultResponse alipayFundTransCommonQueryDefaultResponse = (AlipayFundTransCommonQueryDefaultResponse)ex.ErrorObject;await context.Response.WriteAsync("调用失败:" + alipayFundTransCommonQueryDefaultResponse);//TODO 重发请求,参考上面代码}return;}if (notEnough == true){//余额不足await context.Response.WriteAsync("余额不足");return;}if (isNotRealName == true){//未实名认证await context.Response.WriteAsync("未实名认证");return;}if (accOcupied == true){await context.Response.WriteAsync("多个支付宝账号");return;}if (nameError == true){await context.Response.WriteAsync("收款方姓名不正确");return;}AlipayFundTransUniTransferDefaultResponse errorObject = (AlipayFundTransUniTransferDefaultResponse)e.ErrorObject;await context.Response.WriteAsync("调用失败:" + errorObject);}});app.Run();}}
}