C#实现支付宝转账功能

环境

.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

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

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; } = "";
    }
}

实现方法

cs 复制代码
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);
            #endregion

            var 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 = "";//业务备注长度200
                data.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.10
                data.OrderTitle = "xxx转账";//长度128
                try
                {
                    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();
        }
    }
}
相关推荐
计算机学长felix1 分钟前
基于SpringBoot的“校园交友网站”的设计与实现(源码+数据库+文档+PPT)
数据库·spring boot·毕业设计·交友
Re.不晚4 分钟前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea
老秦包你会6 分钟前
Qt第三课 ----------容器类控件
开发语言·qt
凤枭香9 分钟前
Python OpenCV 傅里叶变换
开发语言·图像处理·python·opencv
ULTRA??13 分钟前
C加加中的结构化绑定(解包,折叠展开)
开发语言·c++
远望清一色29 分钟前
基于MATLAB的实现垃圾分类Matlab源码
开发语言·matlab
confiself39 分钟前
大模型系列——LLAMA-O1 复刻代码解读
java·开发语言
小码的头发丝、1 小时前
Django中ListView 和 DetailView类的区别
数据库·python·django
XiaoLeisj1 小时前
【JavaEE初阶 — 多线程】Thread类的方法&线程生命周期
java·开发语言·java-ee
杜杜的man1 小时前
【go从零单排】go中的结构体struct和method
开发语言·后端·golang