/// <summary> /// 获取退款信息。 /// </summary> /// <param name="root">退款XML Linq节点数据。</param> /// <returns>返回退款信息。</returns> protected virtual IRefundInfo GetRefundInfo(XElement root) { var dict = root.Elements().ToDictionary(t => t.Name.LocalName, t => t.Value); if (dict["sign"] != GetSignature(dict, ShopKey)) { return(null); } RefundInfo info = new RefundInfo(); var count = int.Parse(root.Element("refund_count").Value); info.Items = new IRefundResult[count]; for (int i = 0; i < count; i++) { RefundResult item = new RefundResult(); item.RefundId = root.Element("refund_id_" + i).Value; item.RefundFee = int.Parse(root.Element("refund_fee_" + i).Value); item.Status = (RefundStatus)Enum.Parse(typeof(RefundStatus), root.Element("refund_status_" + i).Value); if (root.Element("refund_channel_" + i) != null) { item.RefundChannel = root.Element("refund_channel_" + i).Value; } if (root.Element("coupon_refund_fee_" + i) != null) { item.Coupon = int.Parse(root.Element("coupon_refund_fee_" + i).Value); } if (root.Element("refund_recv_accout_" + i) != null) { item.Account = root.Element("refund_recv_accout_" + i).Value; } var ncount = int.Parse(root.Element("coupon_refund_count_" + i).Value); item.CouponItems = new Coupon[ncount]; for (int n = 0; n < ncount; n++) { Coupon coupon = new Coupon(); coupon.Id = root.Element("coupon_refund_id_" + i + "_" + n).Value; coupon.Batch = root.Element("coupon_refund_batch_id_" + i + "_" + n).Value; coupon.Fee = int.Parse(root.Element("coupon_refund_fee_" + i + "_" + n).Value); } } return(info); }
/// <summary> /// 微信交易退款。 /// </summary> /// <param name="refundInfo">退款信息。</param> /// <returns></returns> public virtual async Task <IRefundResult> RefundPayment(IRefundOrder refundInfo) { if (refundInfo == null) { throw new ArgumentNullException("refundInfo"); } if (!IsCertificateEnabled) { throw new NotSupportedException("不支持没有证书的操作。"); } var payData = new Dictionary <string, string>(); payData.Add("appid", AppId); payData.Add("mch_id", ShopId); payData.Add("nonce_str", Guid.NewGuid().ToString().Replace("-", ""));//随机字符串 if (refundInfo.TransactionId != null) { payData.Add("transaction_id", refundInfo.TransactionId); } else { payData.Add("out_trade_no", refundInfo.TradeNo); } payData.Add("total_fee", refundInfo.RefundNo); payData.Add("refund_fee", refundInfo.TradeNo); if (refundInfo.RefundCurrency != null) { payData.Add("refund_fee_type", refundInfo.TradeNo); } payData.Add("op_user_id", refundInfo.Operator ?? ShopId); payData.Add("sign", GetSignature(payData, ShopKey)); string backData = await HttpHelper.PostHttp(new Uri(RefundPayUrl), Encoding.UTF8.GetBytes(GetXml(payData)), "text/xml", Encoding.UTF8, 5000, Certificate); XElement root = XDocument.Parse(backData).Element("xml"); if (root.Element("return_code").Value == "FAIL") { string errMsg = root.Element("return_msg").Value; throw new WechatException(errMsg); } if (root.Element("result_code").Value == "FAIL") { string errMsg = root.Element("err_code").Value; throw new WechatException(errMsg); } RefundResult result = new RefundResult(); result.RefundId = root.Element("refund_id").Value; result.RefundChannel = root.Element("refund_channel").Value; result.RefundFee = int.Parse(root.Element("refund_fee").Value); result.RefundNo = root.Element("out_refund_no").Value; result.Status = RefundStatus.PROCESSING; if (root.Element("cash_refund_fee") != null) { result.RefundCash = int.Parse(root.Element("cash_fee").Value); } if (root.Element("coupon_refund_fee") != null) { result.Coupon = int.Parse(root.Element("coupon_refund_fee").Value); } return(result); }