123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- using System;
- using System.Security.Cryptography.X509Certificates;
- using System.Threading.Tasks;
- using WayneCloud.Models;
- using WayneCloud.Models.Models;
- namespace Wechat.PayAPI
- {
- public class Refund
- {
- private const int MAX_REFUND_RETRY_TIMES = 5;
- /***
- * 申请退款完整业务流程逻辑
- * @param transaction_id 微信订单号(优先使用)
- * @param out_trade_no 商户订单号
- * @param total_fee 订单总金额
- * @param refund_fee 退款金额
- * @return 退款结果
- */
- public static async Task<WxPayData> Run(string transaction_id, ElectronicOrderModel order)
- {
- // string out_trade_no, string total_fee, string refund_fee
- //set the default trade_status to PAYERROR
- order.TradeStatus = TradeStatus.PAYERROR;
- string out_refund_no = WxPayApi.GenerateOutTradeNo((WxPayConfig)order.Config);
- Log.Info("Refund", "Refund is processing, out_refund_no = " + out_refund_no);
- int retry_count = 0;
- bool use_unsettled_fund = true;
- while (true)
- {
- WxPayData result = await RequestRefund(transaction_id,
- order.BillNumber,
- order.TotalAmount.ToString(),
- order.NetAmount.ToString(),
- out_refund_no,
- use_unsettled_fund,
- (WxPayConfig)order.Config,
- (X509Certificate2)order.Certification);
- //如果提交退款接口调用失败,则抛异常
- if (!result.IsSet("return_code") || result.GetValue("return_code").ToString() == "FAIL")
- {
- string returnMsg = result.IsSet("return_msg") ? result.GetValue("return_msg").ToString() : "";
- Log.Error("MicroPay", "Micropay API interface call failure, result : " + result.ToXml());
- throw new WxPayException("Micropay API interface call failure, return_msg : " + returnMsg);
- }
- //签名验证
- result.CheckSign((WxPayConfig)order.Config);
- Log.Debug("MicroPay", "Micropay response check sign success");
- //退款成功
- if (result.GetValue("return_code").ToString() == "SUCCESS" &&
- result.GetValue("result_code").ToString() == "SUCCESS")
- {
- Log.Debug("MicroPay", "Micropay refund success, result : " + result.ToXml());
- order.TradeStatus = TradeStatus.SUCCESS;
- return result;
- }
- /******************************************************************
- * 剩下的都是接口调用成功,业务失败的情况
- * ****************************************************************/
- //1)业务结果明确失败
- if (result.GetValue("err_code").ToString() != "BIZERR_NEED_RETRY" &&
- result.GetValue("err_code").ToString() != "SYSTEMERROR" &&
- result.GetValue("err_code").ToString() != "NOTENOUGH")
- {
- Log.Error("MicroPay", "micropay API interface call success, business failure, result : " + result.ToXml());
- return result;
- }
- //2) 使用相同退款单号重试
- if (result.GetValue("err_code").ToString() == "NOTENOUGH")
- {
- use_unsettled_fund = !use_unsettled_fund;
- Log.Debug("MicroPay", "Switched to use the other fund source for refund, use_unsettled_fund = " + use_unsettled_fund);
- }
- retry_count++;
- if (retry_count <= MAX_REFUND_RETRY_TIMES)
- {
- Log.Debug("MicroPay", "Micropay refund retry, retry_count : " + retry_count);
- }
- else
- {
- Log.Error("MicroPay", "Micropay refund max retry times exceeded! Result : " + result.ToXml());
- return result;
- }
- }
- }
- private static async Task<WxPayData> RequestRefund(
- string transaction_id,
- string out_trade_no,
- string total_fee,
- string refund_fee,
- string out_refund_no,
- bool use_unsettled_fund,
- WxPayConfig config,
- X509Certificate2 certification
- )
- {
- if (config == null)
- {
- throw new WxPayException("微信支付,缺少WxPayConfig!");
- }
- WxPayData data = new WxPayData();
- if (!string.IsNullOrEmpty(transaction_id))//微信订单号存在的条件下,则已微信订单号为准
- {
- data.SetValue("transaction_id", transaction_id);
- }
- else//微信订单号不存在,才根据商户订单号去退款
- {
- data.SetValue("out_trade_no", out_trade_no);
- }
- data.SetValue("total_fee", Convert.ToInt32(Decimal.Parse(total_fee) * 100));//订单总金额
- data.SetValue("refund_fee", Convert.ToInt32(Decimal.Parse(refund_fee) * 100));//退款金额
- data.SetValue("out_refund_no", out_refund_no);//商户退款单号
- data.SetValue("op_user_id", config.MCHID);//操作员,默认为商户号
- if (use_unsettled_fund)
- {
- data.SetValue("refund_account", "REFUND_SOURCE_UNSETTLED_FUNDS");
- }
- else
- {
- data.SetValue("refund_account", "REFUND_SOURCE_RECHARGE_FUNDS");
- }
- WxPayData result = await WxPayApi.Refund(data, config, certification);//提交退款申请给API,接收返回数据
- return result;
- }
- }
- }
|