//准备退款参数 public static string prepareRefundParameters(BCRefund refund) { long timestamp = BCUtil.GetTimeStamp(DateTime.Now); JsonData data = new JsonData(); data["app_id"] = BCCache.Instance.appId; data["app_sign"] = BCPrivateUtil.getAppSignatureByMasterSecret(BCCache.Instance.appId, BCCache.Instance.masterSecret, timestamp.ToString()); data["timestamp"] = timestamp; data["channel"] = refund.channel; data["refund_no"] = refund.refundNo; data["bill_no"] = refund.billNo; data["refund_fee"] = refund.refundFee; data["refund_account"] = refund.refundAccount; if (refund.optional != null && refund.optional.Count > 0) { data["optional"] = new JsonData(); foreach (string key in refund.optional.Keys) { data["optional"][key] = refund.optional[key]; } } data["need_approval"] = refund.needApproval; string paraString = data.ToJson(); return paraString; }
/// <summary> /// (预)退款 /// </summary> /// <param name="channel">渠道类型 /// 选填 /// 可以通过enum BCPay.RefundChannel获取 /// ALI: 支付宝 /// WX: 微信 /// UN: 银联 /// JD: 京东 /// YEE: 易宝 /// KUAIQIAN: 快钱 /// BD: 百度 /// 注意:不传channel也能退款的前提是保证所有渠道所有订单号不同,如果出现两个订单号重复,会报错提示传入channel进行区分 /// </param> /// <param name="refundNo">商户退款单号 /// 格式为:退款日期(8位) + 流水号(3~24 位)。不可重复,且退款日期必须是当天日期。流水号可以接受数字或英文字符,建议使用数字,但不可接受“000”。 /// 必填 /// 例如:201506101035040000001 /// </param> /// <param name="billNo">商户订单号 /// 32个字符内,数字和/或字母组合,确保在商户系统中唯一 /// DIRECT_REFUND和PRE_REFUND时必填 /// </param> /// <param name="refundFee">退款金额 /// 只能为整数,单位为分 /// DIRECT_REFUND和PRE_REFUND时必填 /// </param> /// <param name="refundAccount"> /// 微信渠道退款资金来源 /// 1:可用余额退款 /// 0:未结算资金退款(默认使用未结算资金退款) /// </param> /// <param name="optional">附加数据 /// 用户自定义的参数,将会在webhook通知中原样返回,该字段主要用于商户携带订单的自定义数据 /// 选填 /// {"key1":"value1","key2":"value2",...} /// </param> /// <param name="needApproval">是否为预退款 /// 预退款needApproval值传true,直接退款传false /// 如果needApproval值传true,开发者需要调用审核退款接口或者直接去BeeCloud控制台的预退款界面审核退款方能最终退款 /// </param> /// <returns> /// </returns> public static BCRefund BCRefundByChannel(BCRefund refund) { Random random = new Random(); string refundUrl = BCPrivateUtil.getHost() + BCConstants.version + BCConstants.refundURL; string paraString = prepareRefundParameters(refund); try { HttpWebResponse response = BCPrivateUtil.CreatePostHttpResponse(refundUrl, paraString, BCCache.Instance.networkTimeout); string respString = BCPrivateUtil.GetResponseString(response); return handleRefundResult(respString, refund); } catch(Exception e) { var ex = new BCException(e.Message); throw ex; } }
//处理退款Id查询回调 public static BCRefund handleRefundQueryByIdResult(string respString) { JsonData responseData = JsonMapper.ToObject(respString); BCRefund refund = new BCRefund(); if (responseData["result_code"].ToString() == "0") { JsonData refundData = responseData["refund"]; refund.id = refundData["id"].ToString(); refund.title = refundData["title"].ToString(); refund.billNo = refundData["bill_no"].ToString(); refund.refundNo = refundData["refund_no"].ToString(); refund.totalFee = int.Parse(refundData["total_fee"].ToString()); refund.refundFee = int.Parse(refundData["refund_fee"].ToString()); refund.channel = refundData["channel"].ToString(); refund.finish = (bool)refundData["finish"]; refund.result = (bool)refundData["result"]; refund.optional = JsonMapper.ToObject<Dictionary<string, string>>(refundData["optional"].ToString()); refund.messageDetail = refundData["message_detail"].ToString(); refund.createdTime = BCUtil.GetDateTime((long)refundData["create_time"]); } else { var ex = new BCException(responseData["err_detail"].ToString()); throw ex; } return refund; }
//处理退款回调 public static BCRefund handleRefundResult(string respString, BCRefund refund) { JsonData responseData = JsonMapper.ToObject(respString); if (responseData["result_code"].ToString() == "0") { refund.id = responseData["id"].ToString(); try { refund.url = responseData["url"].ToString(); } catch { // } } else { var ex = new BCException(responseData["err_detail"].ToString()); throw ex; } return refund; }
//处理退款条件查询回调 public static List<BCRefund> handleRefundQueryByConditionResult(string respString, bool? needDetail) { JsonData responseData = JsonMapper.ToObject(respString); List<BCRefund> refunds = new List<BCRefund>(); if (responseData["result_code"].ToString() == "0") { if (responseData["refunds"].IsArray) { foreach (JsonData refundData in responseData["refunds"]) { BCRefund refund = new BCRefund(); refund.id = refundData["id"].ToString(); refund.title = refundData["title"].ToString(); refund.billNo = refundData["bill_no"].ToString(); refund.refundNo = refundData["refund_no"].ToString(); refund.totalFee = int.Parse(refundData["total_fee"].ToString()); refund.refundFee = int.Parse(refundData["refund_fee"].ToString()); refund.channel = refundData["channel"].ToString(); refund.finish = (bool)refundData["finish"]; refund.result = (bool)refundData["result"]; refund.optional = JsonMapper.ToObject<Dictionary<string, string>>(refundData["optional"].ToString()); if (needDetail == true) { refund.messageDetail = refundData["message_detail"].ToString(); } refund.createdTime = BCUtil.GetDateTime((long)refundData["create_time"]); refunds.Add(refund); } } } else { var ex = new BCException(responseData["err_detail"].ToString()); throw ex; } return refunds; }
public void prepareRefundParametersTest() { BCRefund refund = new BCRefund("10000000", "20000000", 100); refund.channel = "WX"; refund.optional = new Dictionary<string, string> { { "key1", "value1" }, { "key2", "value2" } }; string paraString = "\"channel\":\"WX\",\"refund_no\":\"20000000\",\"bill_no\":\"10000000\",\"refund_fee\":100,\"refund_account\":0,\"optional\":{\"key1\":\"value1\",\"key2\":\"value2\"},\"need_approval\":false}"; BeeCloud.registerApp("c5d1cba1-5e3f-4ba0-941d-9b0a371fe719", "39a7a518-9ac8-4a9e-87bc-7885f33cf18c", "e14ae2db-608c-4f8b-b863-c8c18953eef2", null); string actual = BCPay.prepareRefundParameters(refund); Assert.IsTrue(actual.Contains(paraString)); }
public void handleRefundResultTest() { BCRefund refund = new BCRefund("10000000", "20000000", 100); string respString = "{\"result_msg\":\"OK\",\"resultCode\":0,\"errMsg\":\"OK:\",\"err_detail\":\"\",\"result_code\":0,\"id\":\"c6bb96d8-f610-48a0-bd72-451886ed3ce9\",\"url\":\"https://mapi.alipay.com/gateway.do?_input_charset=UTF-8&app_id=c37d661d-7e61-49ea-96a5-68c34e83db3b&batch_no=20151222888bb713&batch_num=1&detail_data=2015122221001004460089671321%5E0.01%5E%E5%8D%8F%E8%AE%AE%E9%80%80%E6%AC%BE¬ify_url=http%3A%2F%2Fpayservice.beecloud.cn%2Fbcpay%2FaliRefundDynamic%2Fc37d661d-7e61-49ea-96a5-68c34e83db3b_c6bb96d8-f610-48a0-bd72-451886ed3ce9.php&partner=2088711322600312&refund_date=2015-12-22+06%3A53%3A11&seller_user_id=2088711322600312&service=refund_fastpay_by_platform_pwd&sign=fYf7CmvKF4OqLIsyPcGakgck6uGNz9FIZLrywyc5lbYN6GnXu5zdBvLyIBnbjVPi2Vkz0CD9m2Lbrj%2B%2Fdvr5OznzXrpTSQu481rkLIfSobxNLWNZZG3oZaaEYmwFTHJ%2BGDRInDxAE1hQNcDyrZRDco5pzQ9P7pwRusZnrB8QgJg%3D&sign_type=RSA\",\"out_refund_no_ali_ex\":\"20151222888bb7132088711322600312\"}"; BCRefund actual = BCPay.handleRefundResult(respString, refund); Assert.IsNotNull(actual.url); }
protected void QueryGridView_RowCommand(object sender, GridViewCommandEventArgs e) { if (e.CommandName == "refund") { int rowIndex = Convert.ToInt32(e.CommandArgument); string billNo = bills[rowIndex].billNo; int totalFee = bills[rowIndex].totalFee; if (typeChannel == "Ali") { BCRefund refund = new BCRefund(billNo, DateTime.Today.ToString("yyyyMMdd") + BCUtil.GetUUID().Substring(0, 8), totalFee); refund.channel = BCPay.RefundChannel.ALI.ToString(); try { refund = BCPay.BCRefundByChannel(refund); Response.Redirect(refund.url); } catch (Exception excption) { Response.Write("<span style='color:#00CD00;font-size:20px'>" + excption.Message + "</span><br/>"); } } if (typeChannel == "WX") { BCRefund refund = new BCRefund(billNo, DateTime.Today.ToString("yyyyMMdd") + BCUtil.GetUUID().Substring(0, 8), totalFee); refund.channel = BCPay.RefundChannel.WX.ToString(); try { refund = BCPay.BCRefundByChannel(refund); Response.Write("<script>alert('退款成功!')</script>"); } catch (Exception excption) { Response.Write("<span style='color:#00CD00;font-size:20px'>" + excption.Message + "</span><br/>"); } } if (typeChannel == "UN") { BCRefund refund = new BCRefund(billNo, DateTime.Today.ToString("yyyyMMdd") + BCUtil.GetUUID().Substring(0, 8), totalFee); refund.channel = BCPay.RefundChannel.UN.ToString(); try { refund = BCPay.BCRefundByChannel(refund); Response.Write("<script>alert('退款成功!')</script>"); } catch (Exception excption) { Response.Write("<span style='color:#00CD00;font-size:20px'>" + excption.Message + "</span><br/>"); } } if (typeChannel == "JD") { BCRefund refund = new BCRefund(billNo, DateTime.Today.ToString("yyyyMMdd") + BCUtil.GetUUID().Substring(0, 8), totalFee); refund.channel = BCPay.RefundChannel.JD.ToString(); try { refund = BCPay.BCRefundByChannel(refund); Response.Write("<script>alert('退款成功!')</script>"); } catch (Exception excption) { Response.Write("<span style='color:#00CD00;font-size:20px'>" + excption.Message + "</span><br/>"); } } if (typeChannel == "YEE") { BCRefund refund = new BCRefund(billNo, DateTime.Today.ToString("yyyyMMdd") + BCUtil.GetUUID().Substring(0, 8), totalFee); refund.channel = BCPay.RefundChannel.YEE.ToString(); try { refund = BCPay.BCRefundByChannel(refund); Response.Write("<script>alert('退款成功!')</script>"); } catch (Exception excption) { Response.Write("<span style='color:#00CD00;font-size:20px'>" + excption.Message + "</span><br/>"); } } if (typeChannel == "KUAIQIAN") { BCRefund refund = new BCRefund(billNo, DateTime.Today.ToString("yyyyMMdd") + BCUtil.GetUUID().Substring(0, 8), totalFee); refund.channel = BCPay.RefundChannel.KUAIQIAN.ToString(); try { refund = BCPay.BCRefundByChannel(refund); Response.Write("<script>alert('退款成功!')</script>"); } catch (Exception excption) { Response.Write("<span style='color:#00CD00;font-size:20px'>" + excption.Message + "</span><br/>"); } } if (typeChannel == "BC_GATEWAY") { BCRefund refund = new BCRefund(billNo, DateTime.Today.ToString("yyyyMMdd") + BCUtil.GetUUID().Substring(0, 8), totalFee); refund.channel = BCPay.RefundChannel.BC.ToString(); try { refund = BCPay.BCRefundByChannel(refund); Response.Write("<script>alert('退款成功!')</script>"); } catch (Exception excption) { Response.Write("<span style='color:#00CD00;font-size:20px'>" + excption.Message + "</span><br/>"); } } } }
/// <summary> /// 退款订单查询 /// </summary> /// <param name="channel">渠道类型 /// 根据不同场景选择不同的支付方式 /// 必填 /// 可以通过enum BCPay.QueryChannel获取 /// channel的参数值含义: /// WX_APP: 微信手机APP支付 /// WX_NATIVE: 微信公众号二维码支付 /// WX_JSAPI: 微信公众号支付 /// ALI_APP: 支付宝APP支付 /// ALI_WEB: 支付宝网页支付 /// ALI_QRCODE: 支付宝内嵌二维码支付 /// UN_APP: 银联APP支付 /// UN_WEB: 银联网页支付 /// JD_WAP: 京东wap支付 /// JD_WEB: 京东web支付 /// YEE_WAP: 易宝wap支付 /// YEE_WEB: 易宝web支付 /// KUAIQIAN_WAP: 快钱wap支付 /// KUAIQIAN_WEB: 快钱web支付 /// 注意:不传channel也能查询的前提是保证所有渠道所有订单号不同,如果出现两个订单号重复,会报错提示传入channel进行区分 /// </param> /// <param name="billNo">商户订单号 /// </param> /// <param name="refundNo">商户退款单号 /// </param> /// <param name="startTime">起始时间 /// 毫秒时间戳, 13位, 可以使用BCUtil.GetTimeStamp()方法获取 /// 选填</param> /// <param name="endTime">结束时间 /// 毫秒时间戳, 13位, 可以使用BCUtil.GetTimeStamp()方法获取 /// 选填</param> /// <param name="skip">查询起始位置 /// 默认为0。设置为10表示忽略满足条件的前10条数据 /// 选填 /// </param> /// <param name="limit">查询的条数 /// 默认为10,最大为50。设置为10表示只返回满足条件的10条数据 /// 选填 /// </param> /// <returns> /// BCRefundQuerytResult /// </returns> public static BCRefundQuerytResult BCRefundQueryByCondition(string channel, string billNo, string refundNo, long? startTime, long? endTime, int? skip, int? limit) { Random random = new Random(); string payQueryUrl = BCPrivateUtil.mLocalDefaultHosts[random.Next(0, 4)] + BCConstants.version + BCConstants.refundsURL; long timestamp = BCUtil.GetTimeStamp(DateTime.Now); JsonData data = new JsonData(); data["app_id"] = BCCache.Instance.appId; data["app_sign"] = BCPrivateUtil.getAppSignature(BCCache.Instance.appId, BCCache.Instance.appSecret, timestamp.ToString()); data["timestamp"] = timestamp; data["channel"] = channel; data["bill_no"] = billNo; data["refund_no"] = refundNo; data["start_time"] = startTime; data["end_time"] = endTime; data["skip"] = skip; data["limit"] = limit; string paraString = data.ToJson(); try { string url = payQueryUrl + "?para=" + HttpUtility.UrlEncode(paraString, Encoding.UTF8); HttpWebResponse response = BCPrivateUtil.CreateGetHttpResponse(url, BCCache.Instance.networkTimeout, null, null); string respString = BCPrivateUtil.GetResponseString(response); JsonData responseData = JsonMapper.ToObject(respString); BCRefundQuerytResult result = new BCRefundQuerytResult(); result.resultCode = int.Parse(responseData["result_code"].ToString()); result.resultMsg = responseData["result_msg"].ToString(); if (result.resultCode == 0) { result.count = int.Parse(responseData["count"].ToString()); if (responseData["refunds"].IsArray) { List<BCRefund> refunds = new List<BCRefund>(); foreach (JsonData refundData in responseData["refunds"]) { BCRefund refund = new BCRefund(); refund.title = refundData["title"].ToString(); refund.billNo = refundData["bill_no"].ToString(); refund.refundNo = refundData["refund_no"].ToString(); refund.totalFee = int.Parse(refundData["total_fee"].ToString()); refund.refundFee = int.Parse(refundData["refund_fee"].ToString()); refund.channel = refundData["channel"].ToString(); refund.finish = (bool)refundData["finish"]; refund.result = (bool)refundData["result"]; refund.createdTime = BCUtil.GetDateTime((long)refundData["created_time"]); refunds.Add(refund); } result.refunds = refunds; } } else { result.errDetail = responseData["err_detail"].ToString(); } return result; } catch (Exception e) { BCRefundQuerytResult result = new BCRefundQuerytResult(); result.resultCode = 99; result.resultMsg = e.Message; return result; } }