网站怎么添加二级域名,全栈网站开发,做网站需要买域名吗,福田欧辉氢燃料电池客车目录
需求
基础准备
关键代码
操作界面
编辑
退款订单类及方法
退款功能实现
对帐
支付商家后台相关要点
实时交易帐单查询
精确交易帐单查询
小结 需求
在招聘报名系统里#xff0c;考务费支付是其中一个环节#xff0c;支付方式很多种#xff0c;比如银联、…目录
需求
基础准备
关键代码
操作界面
编辑
退款订单类及方法
退款功能实现
对帐
支付商家后台相关要点
实时交易帐单查询
精确交易帐单查询
小结 需求
在招聘报名系统里考务费支付是其中一个环节支付方式很多种比如银联、微信、支付宝等等。本次我们以微信支付进行举例在考生注册账号、编写简历、报名职位、被初审核通过等一系列基础的条件的具备下可以进入支付考务费的环节笔试费用我们会为其生成一个支付二维码考生支付后无论成功与否都会记录其支付结果状态。
在实际的应用中对于支付成功的考生我们会遇到实现退款的需求只要包括如下场景
1、根据政策规定某些符合全部或部分退款条件的考生。
2、其它未知原因重复支付订单的考生。
3、其它不可抗力需求进行退款的考生。
基础准备
在实现功能前做为企业我们需要申请一个微信服务号并成为微信支付商家。
1、申请服务号
申请成功后会获得到 AppId 和 AppSecret 用于后续开发如关联支付商户、网页授权登录等。
具体指引请参照微信公众平台首页https://mp.weixin.qq.com/cgi-bin/loginpage
2、成为微信支付商家
申请成功后会获得 Mchid 和 paySignKey 用于微信支付、退款等请在商家后台务必关联申请的公众号。
具体指引请参照微信支付平台首页https://pay.weixin.qq.com/index.php/core/home/login
上述两个平台申请成功后请登录微信支付商家平台进行如下图操作 在产品中心、AppID帐号管理、关联 AppID即申请的服务号
另外一个重要配置是支付目录我们写的支付程序需要在这里设置如下图 关键代码
操作界面
界面上会显示最近一笔的微信订单支付情况包括订单号、交费时间、交费金额、退款金额。其中退款金额不能大于成功交费金额否则会返回失败。另外还可以显示微信交易跟踪日志列表信息如果订单号、交易价格、openid、返回信息、交易状态等。
示例界面如下 退款订单类及方法
实现微信退款需要在支付商家平台申请退款证书证书文件保存到自定义的目录中在退款时指定路径。
退款示例代码如下 const string RefundOrderUrl https://api.mch.weixin.qq.com/secapi/pay/refund; //退款申请API地址const string RefundQueryUrl https://api.mch.weixin.qq.com/pay/refundquery; //退款查询API地址
//退款订单明细类
public class RefundOrderDetail{/// summary/// 返回状态码SUCCESS/FAIL 此字段是通信标识非交易标识交易是否成功需要查看trade_state来判断/// /summarypublic string return_code ;/// summary/// 返回信息返回信息如非空为错误原因 签名失败 参数格式校验错误/// /summarypublic string return_msg ;/// summary/// 业务结果,SUCCESS/FAIL/// /summarypublic string result_code ;/// summary/// 错误代码/// /summarypublic string err_code ;/// summary/// 错误代码描述/// /summarypublic string err_code_des ;/// summary/// 公众号ID(微信分配的公众账号 ID)/// /summarypublic string appid ;/// summary/// 商户号(微信支付分配的商户号)/// /summarypublic string mch_id ;/// summary/// 微信支付分配的终端设备号/// /summarypublic string device_info ;/// summary/// 随机字符串不长于32位/// /summarypublic string nonce_str ;/// summary/// 签名/// /summarypublic string sign ;/// summary/// 微信支付订单号/// /summarypublic string transaction_id ;/// summary/// 商户系统的订单号与请求一致。/// /summarypublic string out_trade_no ;public string out_refund_no ;public string refund_id ;public string refund_fee ;public string settlement_refund_fee ;/// summary/// 订单总金额单位为分/// /summarypublic string total_fee ;/// /summarypublic string settlement_total_fee ;public string fee_type ;public string cash_fee ;public string cash_fee_type ;public string cash_refund_fee ;public string coupon_type_0 ;public string coupon_refund_fee ;public string coupon_refund_fee_0 ;public string coupon_refund_count ;public string coupon_refund_id_0 ;}
//退款订单类public class RefundOrder{/// summary/// 公众号ID(微信分配的公众账号 ID)/// /summarypublic string appid ;/// summary/// 商户号(微信支付分配的商户号)/// /summarypublic string mch_id ;/// summary/// 微信支付分配的终端设备号/// /summarypublic string device_info ;/// summary/// 随机字符串不长于 32 位/// /summarypublic string nonce_str ;/// summary/// 签名public string sign ;public string sign_type ;/// summary/// 商户系统内部的订单号,32个字符内、可包含字母,确保在商户系统唯一,详细说明/// /summarypublic string transaction_id ;public string out_trade_no ;public string out_refund_no ;/// summary/// 订单总金额单位为分不能带小数点/// /summarypublic int total_fee 0;public int refund_fee 0;public string refund_fee_type ;public string op_user_id ;/// summarypublic string refund_account ;/// summary}
//查询对帐订单类public class QueryOrder{/// summary/// 公共号ID(微信分配的公众账号 ID)/// /summarypublic string appid ;/// summary/// 商户号(微信支付分配的商户号)/// /summarypublic string mch_id ;/// summary/// 微信订单号优先使用/// /summarypublic string transaction_id ;/// summary/// 商户系统内部订单号/// /summarypublic string out_trade_no ;/// summary/// 随机字符串不长于 32 位/// /summarypublic string nonce_str ;/// summary/// 签名参与签名参数appidmch_idtransaction_idout_trade_nononce_strkey/// /summarypublic string sign ;}//申请退款方法返回退款订单明细类
//参数refundorder为退款订单类, key 为支付签名KEY,cert为证书地址,password 为证书密码public RefundOrderDetail getRefundOrderDetail(RefundOrder refundorder, string key,string cert,string password){string post_data getRefundOrderXml(refundorder, key);string request_data PostXmlAndCertToUrl(RefundOrderUrl, post_data,cert,password);RefundOrderDetail orderdetail new RefundOrderDetail();SortedDictionarystring, string requestXML GetInfoFromXml(request_data);foreach (KeyValuePairstring, string k in requestXML){switch (k.Key){case retuen_code:orderdetail.result_code k.Value;break;case return_msg:orderdetail.return_msg k.Value;break;case result_code:orderdetail.result_code k.Value;break;case err_code:orderdetail.err_code k.Value;break;case err_code_des:orderdetail.err_code_des k.Value;break;case appid:orderdetail.appid k.Value;break;case mch_id:orderdetail.mch_id k.Value;break;case device_info:orderdetail.device_info k.Value;break;case nonce_str:orderdetail.nonce_str k.Value;break;case sign:orderdetail.sign k.Value;break;case transaction_id:orderdetail.transaction_id k.Value;break;case out_trade_no:orderdetail.out_trade_no k.Value;break;case out_refund_no:orderdetail.out_refund_no k.Value;break;case refund_id:orderdetail.refund_id k.Value;break;case refund_fee:orderdetail.refund_fee k.Value;break;case total_fee:orderdetail.total_fee k.Value;break;case settlement_refund_fee:orderdetail.settlement_refund_fee k.Value;break;case settlement_total_fee:orderdetail.settlement_total_fee k.Value;break;case fee_type:orderdetail.fee_type k.Value;break;case cash_fee:orderdetail.cash_fee k.Value;break;case cash_fee_type :orderdetail.cash_fee_type k.Value;break;case cash_refund_fee:orderdetail.cash_refund_fee k.Value;break;case coupon_type_0:orderdetail.coupon_type_0 k.Value;break;case coupon_refund_fee:orderdetail.coupon_refund_fee k.Value;break;case coupon_refund_fee_0:orderdetail.coupon_refund_fee_0 k.Value;break;case coupon_refund_count:orderdetail.coupon_refund_count k.Value;break;case coupon_refund_id_0:orderdetail.coupon_refund_id_0 k.Value;break;default:break;}}return orderdetail;}protected string getRefundOrderXml(RefundOrder refundorder, string key){string return_string string.Empty;SortedDictionarystring, string sParams new SortedDictionarystring, string();sParams.Add(appid, refundorder.appid);sParams.Add(mch_id, refundorder.mch_id);
// sParams.Add(transaction_id, refundorder.transaction_id);sParams.Add(out_trade_no, refundorder.out_trade_no);sParams.Add(nonce_str, refundorder.nonce_str);sParams.Add(out_refund_no, refundorder.out_refund_no);sParams.Add(total_fee, refundorder.total_fee.ToString());sParams.Add(refund_fee, refundorder.refund_fee.ToString());sParams.Add(op_user_id, refundorder.op_user_id);refundorder.sign getsign(sParams, key);sParams.Add(sign, refundorder.sign);//拼接成XML请求数据StringBuilder sbPay new StringBuilder();foreach (KeyValuePairstring, string k in sParams){if (k.Key attach || k.Key body || k.Key sign){sbPay.Append( k.Key ![CDATA[ k.Value ]]/ k.Key );}else{sbPay.Append( k.Key k.Value / k.Key );}}return_string string.Format(xml{0}/xml, sbPay.ToString().TrimEnd(,));return return_string;}public string PostXmlAndCertToUrl(string url, string postData,string cert,string password){string resp string.Empty;ServicePointManager.ServerCertificateValidationCallback new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);//调用证书System.Security.Cryptography.X509Certificates.X509Certificate2 cer new System.Security.Cryptography.X509Certificates.X509Certificate2(cert, password, System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.PersistKeySet | System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.MachineKeySet);HttpWebRequest webrequest (HttpWebRequest)HttpWebRequest.Create(url);webrequest.ClientCertificates.Add(cer);webrequest.Method post;webrequest.ContentType application/x-www-form-urlencoded;webrequest.ContentLength postData.Length;//webrequest.ContentType text/xml;//byte[] data System.Text.Encoding.UTF8.GetBytes(postData);//webrequest.ContentLength data.Length;HttpWebResponse response null;try{StreamWriter swRequestWriter new StreamWriter(webrequest.GetRequestStream());swRequestWriter.Write(postData);if (swRequestWriter ! null)swRequestWriter.Close();response (HttpWebResponse)webrequest.GetResponse();using (StreamReader reader new StreamReader(response.GetResponseStream(), Encoding.UTF8)){resp reader.ReadToEnd();}}catch (Exception exp){throw exp;}finally{if (response ! null)response.Close();}return resp;}public string getNoncestr(){Random random new Random();return GetMD5(random.Next(1000).ToString(), GBK).ToLower().Replace(s, S);}退款功能实现
假设点击退款按钮事件
protected void Button_Click(object sender, EventArgs e)
{string appId “” //服务号的appIdstring paySignKey “” //申请的支付签名KEY;string mch_id “”; //申请的支付商户IDstring OrderID ; //支付订单号string OrderAmount (Convert.ToInt32((float.Parse(Amount.Text) * 100))).ToString(); //订单支付金额Amount.Text 支付金额string RefundOrderAmount (Convert.ToInt32((float.Parse(Amount.Text) * 100))).ToString(); //退款金额Amount.Text这里表示全额退款string RefundOrderID Guid.NewGuid().ToString().Replace(-, ); //生成退款订单号//创建退款订单RefundOrder order new RefundOrder();order.appid appId;order.mch_id mch_id;order.out_trade_no OrderID;order.nonce_str tenpay.getNoncestr();order.out_refund_no RefundOrderID;order.total_fee int.Parse(OrderAmount);order.refund_fee int.Parse(RefundOrderAmount);order.op_user_id mch_id;string cert “d:\\apiclient_cert.p12; //退款证书路径//私钥在安装证书时设置string password ; //证书密码
//创建订单明细类调用getRefundOrderDetail方法进行退款RefundOrderDetail orderdetail getRefundOrderDetail(order, paySignKey, cert, password);string rv (退款订单号: RefundOrderID br);try{rv (退款金额: (double.Parse(orderdetail.total_fee) / 100).ToString() br);}catch (Exception eee){rv (退款金额:br);}rv (b交易状态:nbsp; (orderdetail.result_code SUCCESS ? 退款申请成功 : 退款申请失败) ( orderdetail.result_code ) /bbr);rv (可能的错误描述: orderdetail.err_code_des);
}
对帐
退款申请成功后仅为申请状态需要通过查询退款情况以确定是否完成该功能可以在考生方进行实现考生可随时查询自己的对帐情况。
以下是参考代码该代码可实现支付与退款的查询
protected void queryOrder(object sender, EventArgs e)
{string OrderID ”“; //订单号string paytype ”“ //查询类型支付消费或退款string appId ; //服务号 appidstring paySignKey ; //支付签名keystring mch_id ; //支付商户号if (paytype 消费){try{string openid ”“; QueryOrder order new QueryOrder();order.appid appId;order.mch_id mch_id;order.out_trade_no OrderID;order.nonce_str getNoncestr();OrderDetail orderdetail getOrderDetail(order, paySignKey);string rv (订单号: OrderID br);rv (付款人ID比对识别: (openid orderdetail.openid ? 成功 : 失败) br);rv (交易金额: (double.Parse(orderdetail.total_fee) / 100).ToString() br);rv (b交易状态:nbsp; (orderdetail.trade_state SUCCESS ? 成功 : 失败) ( orderdetail.trade_state ) /bbr);rv (支付交易时间: (orderdetail.time_end ! orderdetail.time_end.Length 14 ? orderdetail.time_end.Substring(0, 4) - orderdetail.time_end.Substring(4, 2) - orderdetail.time_end.Substring(6, 2) orderdetail.time_end.Substring(8, 2) : orderdetail.time_end.Substring(10, 2) : orderdetail.time_end.Substring(12, 2) : ) br);}catch (Exception ex){return;}}else if (paytype 退款){try{RefundOrder order new RefundOrder();order.appid appId;order.mch_id mch_id;order.out_trade_no OrderID;order.nonce_str getNoncestr();RefundOrderDetail orderdetail getRefundQueryOrderDetail(order, paySignKey);string rv (b交易状态:nbsp; (orderdetail.result_code SUCCESS ? 成功 : 失败) ( orderdetail.result_code ) /bbr);rv (其它说明: orderdetail.err_code_des);}catch (Exception ex){}}
}支付商家后台相关要点
实时交易帐单查询
登录后台后该操作可以进行实时交易的帐单对帐功能以备在争议的时候进行查询基本操作如下图 点击交易中心、交易订单、批量订单查询、查询即可下载EXCEL格式的订单。
精确交易帐单查询
登录后台后可查询精确交易帐单该帐单每天1000更新前一天的数据交易我们可以进行CSV格式的下载操作如下图 点击交易中心、交易帐单、打包下载即可请注意图中圈注的提示。
小结
以上提供的代码仅供参考在实际的应用中我们还可以根据业务需要编写其它功能如下载微信官方对帐单导入到应用系统中与业务数据进行对帐以排查争议数据查询订单结果状态以更新业务争议状态信息等。 以上就是自己的一些分享时间仓促不妥之处还请大家批评指正