帶你實(shí)現(xiàn)支付寶/微信金額原路返回

公司首個(gè)外包項(xiàng)目的退換貨流程的退款操作是走原路返回的,而我有幸負(fù)責(zé)這個(gè)功能模塊開(kāi)發(fā)束凑,在實(shí)踐中總結(jié)了一些經(jīng)驗(yàn)挣菲,特此分享出來(lái)富稻。

一、支付寶退款白胀。

支付寶提供了有密以及普通退款接口椭赋,兩者的區(qū)別就是前者不需要申請(qǐng)即時(shí)到賬支付而后者需要,本文使用了有密退款接口或杠;支付寶四要素:PID(合作者id)哪怔,private_key(私鑰,我使用的是RSA加密方式生成的)向抢、alipay_public_key(公鑰认境,支付寶提供的)以及支付賬號(hào)。

1.1先看配置文件:

// 合作身份者ID挟鸠,簽約賬號(hào)叉信,以2088開(kāi)頭由16位純數(shù)字組成的字符串

public static String partner = "";

// 收款支付寶賬號(hào),以2088開(kāi)頭由16位純數(shù)字組成的字符串艘希,一般情況下收款賬號(hào)就是簽約賬號(hào)public static String seller_user_id = partner;

// 商戶(hù)的私鑰,需要PKCS8格式硼身,RSA公私鑰生成

public static String private_key = "";

// 支付寶公鑰

public static String alipay_public_key ?= "";

// 服務(wù)器異步通知頁(yè)面路徑 ?需http://格式的完整路徑,不能加?id=123這類(lèi)自定義參數(shù)覆享,必須外網(wǎng)可以正常訪問(wèn)

public static String notify_url = "http://xxx.xxxx.com/api/refund/refundBack_001";


1.2關(guān)鍵代碼:


/** * 退款操作(請(qǐng)求) * @param response * @return * @throws Exception ?* trade_no 支付寶返回的交易號(hào) * money ?退款金額 */

public String aliRefund(HttpServletRequest request, HttpServletResponse response, String trade_no, String money,String refundId,String batch_no) throws Exception {PrintWriter out = ControllerUtils.getPrintWriter(response, logger, "------------AlipayRefundActionMultiController.aliRefund start------------");

//服務(wù)器異步通知頁(yè)面路徑

?String notify_url;

?String sHtmlText = "";

?try {MapsParaTemp = new HashMap();

?//退款詳細(xì)數(shù)據(jù)鸠姨,必填,格式(支付寶交易號(hào)^退款金額^備注)淹真,多筆請(qǐng)用#隔開(kāi)

?String detail_data = trade_no + "^" + money + "^退款";

?sParaTemp.put("detail_data", detail_data);//退款詳情

?sParaTemp.put("service", AlipayConfig.service);//

?sParaTemp.put("partner", AlipayConfig.partner);//合作者id

?sParaTemp.put("_input_charset", AlipayConfig.input_charset);//字符集格式

sParaTemp.put("notify_url", AlipayConfig.notify_url);//回調(diào)地址

sParaTemp.put("seller_email", "商家賬號(hào)");//賬號(hào)

sParaTemp.put("refund_date", UtilDate.getDateFormatter());//退款時(shí)間

sParaTemp.put("batch_no", batch_no);//批次號(hào),必填连茧,格式:當(dāng)天日期[8位]+序列號(hào)[3至24位]核蘸,如:201603081000001

sParaTemp.put("batch_num", "1"); //退款筆數(shù)巍糯,必填,參數(shù)detail_data的值中客扎,“#”字符出現(xiàn)的數(shù)量加1祟峦,最大支持1000筆(即“#”字符出現(xiàn)的數(shù)量999個(gè))

sHtmlText = AlipaySubmit.buildRequest(sParaTemp, "get", "確認(rèn)");

} catch (Exception e) {

e.printStackTrace();

}

return sHtmlText;

}


注意:此處的交易號(hào)必須是你支付時(shí)保存的交易號(hào),以及退款金額不能大于實(shí)付金額且不能<=0徙鱼,否則無(wú)法調(diào)起支付宅楞。我是將退款信息用一個(gè)form表單封裝起來(lái)然后以流的方式輸出,前端頁(yè)面只需要拿到該信息然后填充到一個(gè)div中袱吆。

1.3表單封裝:

/** * 建立請(qǐng)求厌衙,以表單HTML形式構(gòu)造(默認(rèn)) * @param sParaTemp 請(qǐng)求參數(shù)數(shù)組 * @param strMethod 提交方式。兩個(gè)值可選:post绞绒、get * @param strButtonName 確認(rèn)按鈕顯示文字 * @return 提交表單HTML文本 */

public static String buildRequest(Map < String, String > sParaTemp, String strMethod, String strButtonName){ ? ?//待請(qǐng)求參數(shù)數(shù)組 ? ?

Map < String, ? ?String > sPara = buildRequestPara(sParaTemp); ? ?

List < String > keys = new ArrayList < String > (sPara.keySet()); ? ? ? ?

StringBuffer sbHtml = new StringBuffer(); ? ? ?

sbHtml.append(""); ? ? ? ?

for (int i = 0; i < keys.size(); i++) ? ?{ ? ? ?

String name = (String)keys.get(i); ? ? ? ?

String value = (String)sPara.get(name); ? ? ? ? ? ? ?

sbHtml.append(""); ? ?

} ? ?

//submit按鈕控件請(qǐng)不要含有name屬性 ? ?

sbHtml.append(""); ? ?

sbHtml.append("document.forms['alipaysubmit'].submit();"); ? ? ? ?

return sbHtml.toString();}

1.4前端頁(yè)面拿到信息后進(jìn)行填充:



1.5效果展示:


二婶希、微信退款。

2.1配置文件


2.2退款前提條件:

商戶(hù)必須開(kāi)通微信支付功能蓬衡,開(kāi)發(fā)人員要拿到賬號(hào)以及證書(shū)(重點(diǎn))喻杈,退款金額不能大于實(shí)付價(jià)、小于等于0狰晚,并且傳入的實(shí)際支付價(jià)必須跟微信那邊保持一致筒饰,否則無(wú)法完成退款操作。

2.2關(guān)鍵代碼:

private String doRefundByWX(String money, String bankSerialNumber, long numberCount, String no,String sumAmout) throws UnrecoverableKeyException, KeyManagementException, KeyStoreException, NoSuchAlgorithmException, IOException{

String result="";

String appid=WeiXinUtil.appid;//應(yīng)用ID

String mch_id=WeiXinUtil.mch_id;//商戶(hù)號(hào)

String nonce_str=WeiXinUtil.CreateNoncestr();//隨機(jī)字符串

String transaction_id=bankSerialNumber;//微信訂單號(hào)

String out_refund_no=no;//商戶(hù)退款單號(hào)

Double total_fee=0d;

try {

total_fee = StringUtil.getDouble(sumAmout);

} catch (NumberFormatException e)

{e.printStackTrace();}

catch (Exception e) {

e.printStackTrace();

}

long totalAmount = new BigDecimal(total_fee * 100d).longValue();//總金額以分為單位Double refund_fee=Double.parseDouble(money);

long Amount = new BigDecimal(refund_fee * 100d).longValue();//退款金額以分為單位

String op_user_id=WeiXinUtil.mch_id;//操作員帳號(hào), 默認(rèn)為商戶(hù)號(hào) /簽名算法SortedMapSortedMap = new TreeMap();

SortedMap.put("appid", appid);

SortedMap.put("mch_id",mch_id);

SortedMap.put("nonce_str",nonce_str);

SortedMap.put("transaction_id", transaction_id);

SortedMap.put("out_refund_no", out_refund_no);

SortedMap.put("total_fee",String.valueOf(totalAmount));

SortedMap.put("refund_fee", String.valueOf(Amount));

SortedMap.put("op_user_id", op_user_id);

String sign=WeiXinUtil.createSign("UTF-8",SortedMap);

//獲取最終待發(fā)送的數(shù)據(jù)

String requestXml=WeiXinUtil.getRequestXml(SortedMap);

//(2)建立連接并發(fā)送數(shù)據(jù)

result=WeixinSendPost(requestXml);

return result;

}

2.3退款操作:

先申明一點(diǎn):微信退款沒(méi)有提供跳轉(zhuǎn)頁(yè)面壁晒,也就是一點(diǎn)擊退款瓷们,只要信息正確就會(huì)自動(dòng)打錢(qián)到退款賬戶(hù)。





三讨衣、關(guān)于保存微信支付换棚、支付寶交易號(hào)作為退款字段的代碼圖(訂單支付的回調(diào)方法):


備注:由于時(shí)間問(wèn)題就不上全部代碼,如若要具體代碼請(qǐng)關(guān)注我反镇,如果響應(yīng)激烈我將會(huì)將代碼放到GitHub固蚤。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市歹茶,隨后出現(xiàn)的幾起案子夕玩,更是在濱河造成了極大的恐慌,老刑警劉巖惊豺,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件燎孟,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡尸昧,警方通過(guò)查閱死者的電腦和手機(jī)揩页,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)烹俗,“玉大人爆侣,你說(shuō)我怎么就攤上這事萍程。” “怎么了兔仰?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵茫负,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我乎赴,道長(zhǎng)忍法,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任榕吼,我火速辦了婚禮饿序,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘友题。我一直安慰自己嗤堰,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布度宦。 她就那樣靜靜地躺著踢匣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪戈抄。 梳的紋絲不亂的頭發(fā)上离唬,一...
    開(kāi)封第一講書(shū)人閱讀 49,760評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音划鸽,去河邊找鬼输莺。 笑死,一個(gè)胖子當(dāng)著我的面吹牛裸诽,可吹牛的內(nèi)容都是我干的嫂用。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼丈冬,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼嘱函!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起埂蕊,我...
    開(kāi)封第一講書(shū)人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤往弓,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后蓄氧,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體函似,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年喉童,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了撇寞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蔑担,靈堂內(nèi)的尸體忽然破棺而出露氮,到底是詐尸還是另有隱情,我是刑警寧澤钟沛,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站局扶,受9級(jí)特大地震影響恨统,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜三妈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一畜埋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧畴蒲,春花似錦悠鞍、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至蔫骂,卻和暖如春么翰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背辽旋。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工浩嫌, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人补胚。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓码耐,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親溶其。 傳聞我的和親對(duì)象是個(gè)殘疾皇子骚腥,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容