一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務(wù)器之家 - 編程語言 - JAVA教程 - SSH框架網(wǎng)上商城項(xiàng)目第21戰(zhàn)之詳解易寶支付的流程

SSH框架網(wǎng)上商城項(xiàng)目第21戰(zhàn)之詳解易寶支付的流程

2020-05-11 11:38eson_15 JAVA教程

這篇文章主要為大家詳細(xì)介紹了SSH框架網(wǎng)上商城項(xiàng)目第21戰(zhàn)之易寶支付的流程,感興趣的小伙伴們可以參考一下

這一節(jié)我們先寫一個(gè)簡(jiǎn)單點(diǎn)的Demo來測(cè)試易寶支付的流程,熟悉這個(gè)流程后,再做實(shí)際的開發(fā),因?yàn)槭且粋€(gè)Demo,所以我沒有考慮一些設(shè)計(jì)模式的東西,就是直接實(shí)現(xiàn)支付功能。實(shí)現(xiàn)支付功能需要易寶給我們提供的API。那么問題來了,使用第三方支付平臺(tái)最主要的一件事就是獲取該平臺(tái)的API,我們首先得獲取他們的API以及開發(fā)文檔,然后才可以做進(jìn)一步的開發(fā)。

1. 獲取易寶的API

獲取API的第一步,要在易寶上注冊(cè)一個(gè)賬號(hào),這個(gè)賬號(hào)是商家的賬號(hào),后面買家付款后,會(huì)將錢款存入該賬號(hào)中,然后商家自己提取到銀行卡,易寶在提取過程中收取一定的手續(xù)費(fèi)。這就是易寶的盈利模式。但是注冊(cè)成功需要前提,那就是自己得有一個(gè)網(wǎng)站,或者是一個(gè)公司,吧啦吧啦等東西,反正就是你得有資格申請(qǐng),這點(diǎn)易寶會(huì)審核的,滿足了才會(huì)允許你注冊(cè),才會(huì)給你提供他們的接口,不是所有人都可以注冊(cè)的。我用的也是別人注冊(cè)好的,我自己啥也沒有……也沒法注冊(cè)……屌絲一個(gè),大家懂的~但是一般在公司里開發(fā)的話,就不會(huì)存在這個(gè)問題,賬號(hào)肯定都是有的,最重要的是要掌握開發(fā)流程和相關(guān)技術(shù)~

2. 測(cè)試支付流程

有了官方提供的API和技術(shù)文檔后,就可以著手開發(fā)了,在這里主要寫一個(gè)簡(jiǎn)單的demo來測(cè)試一下易寶支付的流程,demo的結(jié)構(gòu)很簡(jiǎn)單,一個(gè)servlet,一個(gè)filter,兩個(gè)jsp頁(yè)面和一個(gè)加密的工具類。servlet與易寶服務(wù)器端打交道,我們做一些跟易寶接口相關(guān)的處理,filter是用來處理可能出現(xiàn)的中文亂碼問題,兩個(gè)jsp中一個(gè)是前臺(tái)頁(yè)面。
我們先來分析一下支付請(qǐng)求的過程,如下所示:

SSH框架網(wǎng)上商城項(xiàng)目第21戰(zhàn)之詳解易寶支付的流程

好了,下面我們具體分析一下demo中的相關(guān)代碼:

2.1 前臺(tái)測(cè)試頁(yè)面

首先看一下前臺(tái)頁(yè)面index.jsp的具體代碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
 <head>
 
  <title>前臺(tái)首頁(yè)</title>
 </head>
 
 <body>
  <h1>在線支付演示</h1>
  <form action="${pageContext.request.contextPath }/servlet/PayServlet" method="post">
     此次購(gòu)物訂單編號(hào)<input type="text" name="p2_Order" /><br>
     money<input type="text" name="p3_Amt" value="0.01"/><br>
     工商銀行<input type="radio" value="ICBC-NET" name="pd_FrpId">
     建設(shè)銀行<input type="radio" value="CCB-NET" name="pd_FrpId"><br>
     <input type="submit" value="submit" />
     <input type="hidden" value="pay" name="status"/>
  </form>
 </body>
</html>

從上面的jsp頁(yè)面中可以看出,這些input標(biāo)簽中的name屬性值都很奇怪,pi_功能(i=0,1,2,…,9),當(dāng)然i還有其他的值,這得參照易寶的官方文檔,這些name表示相對(duì)應(yīng)的屬性,到時(shí)候會(huì)傳到sevlet處理,關(guān)于這些屬性值,我截了個(gè)圖,如下:

SSH框架網(wǎng)上商城項(xiàng)目第21戰(zhàn)之詳解易寶支付的流程  

這些參數(shù)名有些在實(shí)際項(xiàng)目中是前臺(tái)傳進(jìn)來的,比如上面寫的訂單號(hào),要付多少錢,這些在訂單確認(rèn)的時(shí)候都會(huì)帶過去,那么其他參數(shù),必填的話,需要在servlet里指定好,非必填字段的話,就可以為空,這里的空不是null,而是”“,后面servlet中會(huì)提到。
再看看兩個(gè)銀行中對(duì)應(yīng)的value值也是固定的,易寶會(huì)提供它所支持的所有銀行的value值,這些都是固定的,不能修改的。這里就寫兩個(gè)銀行測(cè)試一下效果。
最后那個(gè)隱藏字段是用來在servlet中做判斷的,是支付還是支付成功后的返回,下面在sevlet中會(huì)說明。

2.2 Servlet處理請(qǐng)求

servlet主要處理與易寶的相關(guān)請(qǐng)求,里面有兩個(gè)部分的內(nèi)容,一部分是向易寶發(fā)送明文和密文,另一部分是判斷易寶發(fā)過來的明文和密文,我們看看demo中具體的實(shí)現(xiàn)代碼:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
public class PayServlet extends HttpServlet {
  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    String status = request.getParameter("status");
    if (status.equals("pay")) { //index.jsp中隱藏字段傳來的是pay,所以處理支付這部分
      // 加密的密鑰,用在加密算法中,由支付中介提供,每個(gè)商家獨(dú)一無二的
      String keyValue = "w0P75wMZ203fr46r5i70V556WHFa94j14yW5J6vuh4yo3nRl5jsqF3c41677";
      // 1: 給參數(shù)賦值,這些參數(shù)(即明文)都是易寶官方提供的文檔中所定義的,名字我們不能改
      String p0_Cmd = formatString("Buy");
      String p1_MerId = formatString("10000940764");
      String p2_Order = formatString(request.getParameter("p2_Order"));
      String p3_Amt = formatString(request.getParameter("p3_Amt"));
      String p4_Cur = formatString("CNY");
      String p5_Pid = "";
      String p6_Pcat = "";
      String p7_Pdesc = "";
      String p8_Url = "http://www.tongji.edu.cn";//這是支付成功后跳轉(zhuǎn)到的頁(yè)面,可以設(shè)為商城首頁(yè),這個(gè)demo就用同濟(jì)大學(xué)主頁(yè)好了……
      String p9_SAF = "0";
      String pa_MP = "";
      String pd_FrpId = formatString(request.getParameter("pd_FrpId"));
      pd_FrpId = pd_FrpId.toUpperCase();
      String pr_NeedResponse = "0";
 
      String hmac = formatString("");//hmac是用來存儲(chǔ)密文的
      /*上面所有的明文都用都用formatString方法包裝了一下,該方法在下面,主要是將null轉(zhuǎn)換成""
       *因?yàn)閚ull是無法轉(zhuǎn)換成密文的*/
 
      // 解決數(shù)據(jù)安全性問題: 把明文加密--->密文  然后把明文和密文都交給易寶
      // 易寶拿到數(shù)據(jù)后,把傳過來的明文加密, 和傳過來密文比較,
      // 如果相等數(shù)據(jù)沒有被篡改 (商家與易寶加密時(shí)都用的是相同key)
 
      // 把明文數(shù)據(jù)追加到StringBuffer,注意追加順序不能改,否則生成的密文會(huì)不同的,
      // 要嚴(yán)格按照易寶的官方文檔說名來寫才行,因?yàn)橐讓毮沁吘褪歉鶕?jù)文檔中的順序追加的
      StringBuffer infoBuffer = new StringBuffer();
      infoBuffer.append(p0_Cmd);
      infoBuffer.append(p1_MerId);
      infoBuffer.append(p2_Order);
      infoBuffer.append(p3_Amt);
      infoBuffer.append(p4_Cur);
      infoBuffer.append(p5_Pid);
      infoBuffer.append(p6_Pcat);
      infoBuffer.append(p7_Pdesc);
      infoBuffer.append(p8_Url);
      infoBuffer.append(p9_SAF);
      infoBuffer.append(pa_MP);
      infoBuffer.append(pd_FrpId);
      infoBuffer.append(pr_NeedResponse);
      // 加密后的密文存儲(chǔ)到了hmac中,加密算法易寶會(huì)提供的,因?yàn)樗沁呉驳糜孟嗤乃惴?/code>
      hmac = DigestUtil.hmacSign(infoBuffer.toString(), keyValue);
      // 把明文和密文都存儲(chǔ)到request.setAttribute中
      request.setAttribute("p0_Cmd", p0_Cmd);
      request.setAttribute("p1_MerId", p1_MerId);
      request.setAttribute("p2_Order", p2_Order);
      request.setAttribute("p3_Amt", p3_Amt);
      request.setAttribute("p4_Cur", p4_Cur);
      request.setAttribute("p5_Pid", p5_Pid);
      request.setAttribute("p6_Pcat", p6_Pcat);
      request.setAttribute("p7_Pdesc", p7_Pdesc);
      request.setAttribute("p8_Url", p8_Url);
      request.setAttribute("p9_SAF", p9_SAF);
      request.setAttribute("pa_MP", pa_MP);
      request.setAttribute("pd_FrpId", pd_FrpId);
      request.setAttribute("pr_NeedResponse", pr_NeedResponse);
      request.setAttribute("hmac", hmac);
      System.out.println("hmac-->" + hmac);
      //跳轉(zhuǎn)到reqpay.jsp中,將這些信息提交到易寶
      request.getRequestDispatcher("/reqpay.jsp").forward(request,
          response);
    } else if (status.equals("success")) {//易寶那邊傳來的是success,處理返回驗(yàn)證部分
      PrintWriter out = response.getWriter();
      String keyValue = "w0P75wMZ203fr46r5i70V556WHFa94j14yW5J6vuh4yo3nRl5jsqF3c41677";
      // 獲取所有的明文
      String r0_Cmd = formatString(request.getParameter("r0_Cmd"));
      String p1_MerId = request.getParameter("p1_MerId");
      String r1_Code = formatString(request.getParameter("r1_Code"));
      String r2_TrxId = formatString(request.getParameter("r2_TrxId"));
      String r3_Amt = formatString(request.getParameter("r3_Amt"));
      String r4_Cur = formatString(request.getParameter("r4_Cur"));
      String r5_Pid = new String(formatString(
          request.getParameter("r5_Pid")).getBytes("iso-8859-1"),
          "UTF-8");
      String r6_Order = formatString(request.getParameter("r6_Order"));
      String r7_Uid = formatString(request.getParameter("r7_Uid"));
      String r8_MP = new String(formatString(
          request.getParameter("r8_MP")).getBytes("iso-8859-1"),
          "UTF-8");
      String r9_BType = formatString(request.getParameter("r9_BType"));
      // 對(duì)明文進(jìn)行數(shù)據(jù)追加
      String hmac = formatString(request.getParameter("hmac"));
      StringBuffer infoBuffer = new StringBuffer();
      infoBuffer.append(p1_MerId);
      infoBuffer.append(r0_Cmd);
      infoBuffer.append(r1_Code);
      infoBuffer.append(r2_TrxId);
      infoBuffer.append(r3_Amt);
      infoBuffer.append(r4_Cur);
      infoBuffer.append(r5_Pid);
      infoBuffer.append(r6_Order);
      infoBuffer.append(r7_Uid);
      infoBuffer.append(r8_MP);
      infoBuffer.append(r9_BType);
      // 對(duì)返回的明文進(jìn)行加密
      String md5 = DigestUtil.hmacSign(infoBuffer.toString(), keyValue);
      // 判斷加密的密文與傳過來的數(shù)據(jù)簽名是否相等
      boolean isOK = md5.equals(hmac);
      if (isOK && r1_Code.equals("1")) {//r1_Code為1表示成功
        //把支付成功的訂單狀態(tài)改成已支付,并個(gè)給用戶顯示支付成功信息
        //調(diào)用郵件服務(wù)接口,短信發(fā)送服務(wù)等
        //這里就打印一句話唄~
        out.println("訂單編號(hào)為:" + r6_Order + "支付金額為:" + r3_Amt);
 
      } else {
        out.println("fail !!!!");
      }
    }
  }
 
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
 
    doGet(request, response);
  }
 
  String formatString(String text) {
    if (text == null) {
      return "";
    }
    return text;
  }
}

2.3 加密算法

明文轉(zhuǎn)密文所用到的加密算法由易寶提供,我們只需要用它將明文轉(zhuǎn)為密文即可,算法如下:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
public class DigestUtil {
 
  private static String encodingCharset = "UTF-8";
 
  public static String hmacSign(String aValue, String aKey) {
    byte k_ipad[] = new byte[64];
    byte k_opad[] = new byte[64];
    byte keyb[];
    byte value[];
    try {
      keyb = aKey.getBytes(encodingCharset);
      value = aValue.getBytes(encodingCharset);
    } catch (UnsupportedEncodingException e) {
      keyb = aKey.getBytes();
      value = aValue.getBytes();
    }
 
    Arrays.fill(k_ipad, keyb.length, 64, (byte) 54);
    Arrays.fill(k_opad, keyb.length, 64, (byte) 92);
    for (int i = 0; i < keyb.length; i++) {
      k_ipad[i] = (byte) (keyb[i] ^ 0x36);
      k_opad[i] = (byte) (keyb[i] ^ 0x5c);
    }
 
    MessageDigest md = null;
    try {
      md = MessageDigest.getInstance("MD5");
    } catch (NoSuchAlgorithmException e) {
 
      return null;
    }
    md.update(k_ipad);
    md.update(value);
    byte dg[] = md.digest();
    md.reset();
    md.update(k_opad);
    md.update(dg, 0, 16);
    dg = md.digest();
    return toHex(dg);
  }
 
  public static String toHex(byte input[]) {
    if (input == null)
      return null;
    StringBuffer output = new StringBuffer(input.length * 2);
    for (int i = 0; i < input.length; i++) {
      int current = input[i] & 0xff;
      if (current < 16)
        output.append("0");
      output.append(Integer.toString(current, 16));
    }
 
    return output.toString();
  }
 
  public static String getHmac(String[] args, String key) {
    if (args == null || args.length == 0) {
      return (null);
    }
    StringBuffer str = new StringBuffer();
    for (int i = 0; i < args.length; i++) {
      str.append(args[i]);
    }
    return (hmacSign(str.toString(), key));
  }
 
  /**
   * @param aValue
   * @return
   */
  public static String digest(String aValue) {
    aValue = aValue.trim();
    byte value[];
    try {
      value = aValue.getBytes(encodingCharset);
    } catch (UnsupportedEncodingException e) {
      value = aValue.getBytes();
    }
    MessageDigest md = null;
    try {
      md = MessageDigest.getInstance("SHA");
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
      return null;
    }
    return toHex(md.digest(value));
 
  }
 
  //我自己用來測(cè)試的
  public static void main(String[] args) {
    // 參數(shù)1: 明文(要加密的數(shù)據(jù)) 參數(shù)2: 密鑰
    System.out.println(DigestUtil.hmacSign("11111", "abc"));
    System.out.println(DigestUtil.hmacSign("11111", "abd"));
  // 解決數(shù)據(jù)安全性問題: 把明文加密--->密文  然后把明文和密文都交給易寶
  // 易寶拿到數(shù)據(jù)后,把傳過來的明文加密, 和傳過來密文比較,如果相等數(shù)據(jù)沒有被篡改 (商家與易寶加密時(shí)都用的是相同key)  
  }
}

加密算法也不去過多的研究了,好像是md5二代加密算法,反正把明文扔進(jìn)去,肯定加密成密文就行了。下面再看一下reqpay.jsp頁(yè)面:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<%@page language="java" contentType="text/html;charset=gbk"%>
<html>
  <head>
    <title>To YeePay Page
    </title>
  </head>
  <body>
    <form name="yeepay" action='https://www.yeepay.com/app-merchant-proxy/node' method='POST' target="_blank">
      <input type='hidden' name='p0_Cmd'  value='${requestScope.p0_Cmd}'>
      <input type='hidden' name='p1_MerId' value='${requestScope.p1_MerId}'>
      <input type='hidden' name='p2_Order' value='${requestScope.p2_Order}'>
      <input type='hidden' name='p3_Amt'  value='${requestScope.p3_Amt}'>
      <input type='hidden' name='p4_Cur'  value='${requestScope.p4_Cur}'>
      <input type='hidden' name='p5_Pid'  value='${requestScope.p5_Pid}'>
      <input type='hidden' name='p6_Pcat' value='${requestScope.p6_Pcat}'>
      <input type='hidden' name='p7_Pdesc' value='${requestScope.p7_Pdesc}'>
      <input type='hidden' name='p8_Url'  value='${requestScope.p8_Url}'>
      <input type='hidden' name='p9_SAF'  value='${requestScope.p9_SAF}'>
      <input type='hidden' name='pa_MP'  value='${requestScope.pa_MP}'>
      <input type='hidden' name='pd_FrpId' value='${requestScope.pd_FrpId}'>
      <input type="hidden" name="pr_NeedResponse" value="${requestScope.pr_NeedResponse}">
      <input type='hidden' name='hmac' value='${requestScope.hmac}'>
      <input type='submit' />
    </form>
  </body>
</html>

其實(shí)該頁(yè)面很簡(jiǎn)單,就是將明文和密文一起通過<form>表單傳到易寶,易寶的接收url為https://www.yeepay.com/app-merchant-proxy/node,這也是易寶官方提供的,我們寫成這個(gè)就可以了。其實(shí)就一個(gè)submit按鈕,點(diǎn)擊submit按鈕就能將明文和密文提交過去了。我們看一下測(cè)試結(jié)果:

3. 測(cè)試支付結(jié)果

  簡(jiǎn)陋的測(cè)試前臺(tái)index.jsp~~~:

SSH框架網(wǎng)上商城項(xiàng)目第21戰(zhàn)之詳解易寶支付的流程

提交后會(huì)到reqpay,jsp,點(diǎn)擊提交按鈕后的效果如下,我們將工行和建行都測(cè)一下:

SSH框架網(wǎng)上商城項(xiàng)目第21戰(zhàn)之詳解易寶支付的流程

SSH框架網(wǎng)上商城項(xiàng)目第21戰(zhàn)之詳解易寶支付的流程 

支付流程都沒啥問題,本來準(zhǔn)備去工行交個(gè)1分錢看一下支付完成后的結(jié)果,結(jié)果發(fā)現(xiàn)U盾過期了,因?yàn)楝F(xiàn)在用支付寶比較方便嘛……就沒去更新U盾了,但是我開通過工行的e支付,所以上面那個(gè)界面中也可以使用e支付,于是我就很大方的付了1分錢~~結(jié)果如下:

SSH框架網(wǎng)上商城項(xiàng)目第21戰(zhàn)之詳解易寶支付的流程 

然后會(huì)跳轉(zhuǎn)到我們之前指定的頁(yè)面,也就是同濟(jì)大學(xué)咯……好了,測(cè)試完成了,整個(gè)支付流程結(jié)束!
這一節(jié)主要是通過一個(gè)簡(jiǎn)單的demo測(cè)試一下,看能否和銀行的支付界面接上,現(xiàn)在測(cè)試是沒問題的,已經(jīng)接上了,后面只要照常支付即可。簡(jiǎn)單的demo就介紹到這吧,后面就真正繼續(xù)我們之前的網(wǎng)上商城項(xiàng)目的在線支付模塊的開發(fā)了。

原文地址:http://blog.csdn.net/eson_15/article/details/51447492

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 久久爽狠狠添AV激情五月 | 91原创国产 | 大学生初次破苞免费视频 | daring国家队在线观看樱花动漫 | 精品视频一区二区观看 | 国语视频高清在线观看 | 2020韩国三级理论在线观看 | 亚洲国产精品久久精品成人网站 | 性xxxx中国老妇506070 | 美女岳肉太深了使劲 | 男女乱淫真视频播放网站 | 99热色 | 毛片免费观看 | 67194久久| 国产精品全国探花在线观看 | 欧美一级欧美三级 | 国产在线视频一区二区三区 | chinese国产打屁股 | 国产日韩免费视频 | 波多野结中文字幕在线69视频 | 王晶经典三级 | 99视频有精品视频免费观看 | 久久精品WWW人人爽人人 | 草莓社区| 亚洲va精品中文字幕 | 无遮挡h肉动漫高清在线 | 精品国产乱码久久久人妻 | 日本人成年视频在线观看 | 狠狠色成人综合 | 男人天堂日韩 | 沉沦艳妇杨幂肉体小说 | 韩日视频在线观看 | 果冻传媒新在线观看免费 | 特黄特级高清免费视频毛片 | 午夜理论片YY4399影院 | 欧美一区二区三区不卡视频 | 97porm自拍视频区原创 | 亚洲精品AV无码喷奶水糖心 | 色综合天天综合 | 加勒比一本大道香蕉在线视频 | 欧美一二区视频 |