客户在系统内下订单 -> 系统根据订单生成支付宝接口url -> 客户通过url使用支付宝(网上银行)付款 -> 支付宝将客户的付款完成信息发送给电子商务系统 -> 系统收到支付宝信息后确定客户订单已经付款 -> 进行发货等后续流程。
其实这个流程与以前讲paypal接口的基本类似,都是为了实现订单的自动付款确认。
paypal与支付宝在使用时候有一点区别:paypal接口是直接通过一个form提交给paypal网站;而支付宝是通过一个url跳转到支付宝网站的。
在开始下面的内容之前,你要先有一个支付宝账户,如果要集成支付宝接口,你还必须申请开通服务(关于如何开通,可以直接到支付宝网站上申请).在服务开通后,支付宝会给你2个字符串编号:1个partnerId(合作伙伴ID),还有1个securityCode(安全码).当你拿到这2个码的时候就可以开始下面的内容了.
(1)如何调用支付宝接口?(将客户的订单信息按照既定的规则生成一个url跳转到支付宝网站)
通过下面方法[makeOrderAlipayUrl(HttpServletRequest httpRequest,Order order)]的调用得到支付宝的url,然后进行跳转(response.sendRedirect(url);).
1. Java代码
2. /**
3. * 根据订单生成支付宝接口URL.
4. * @param httpRequest
5. * @param order 订单实例
6. * @return
7. * @throws Exception
8. */
9. public static String makeOrderAlipayUrl(HttpServletRequest
httpRequest,Order order) throws Exception {
10. HashMap hm = new HashMap();
11. hm.put(\"_input_charset\采用相同的编码方式
12. hm.put(\"body\您在www.xxx.com上的订单\");//填写在跳到支付宝页面上显示的付款内容信息
13. hm.put(\"discount\填写折扣信息 -5表示抵扣5元
14. hm.put(\"logistics_fee\物流费用
15. hm.put(\"logistics_payment\物流费用支付人 BUYER_PAY=买家支付物流费用
16. hm.put(\"logistics_type\物流方式
17. hm.put(\"notify_url\客户付款后,支付宝调用的页面
18. hm.put(\"out_trade_no\外部交易号,最好具有唯一性,在获取支付宝发来的付款信息时使用.
19. hm.put(\"partner\合作伙伴ID)
20. hm.put(\"agent\合作伙伴ID)
21. hm.put(\"payment_type\支付类型 1=商品购买,2=服务购买,...
22. hm.put(\"price\订单金额信息
23. hm.put(\"quantity\订单商品数量,一般都是写1,它是按照整个订单包来计算
24. hm.put(\"return_url\客户付款成功后,显示给客户的页面
25. hm.put(\"seller_email\你的支付宝账户email
26. hm.put(\"service\user=直接付款,trade_create_by_buyer 担保付款
27. hm.put(\"subject\的订单\");//填写在跳到支付宝页面上显示的付款标题信息
28. String payGateway =
\"https://www.alipay.com/cooperate/gateway.do?\";//跳转到支付宝的url头
29. return
makeUrl(hm,securityCode,httpRequest.getCharacterEncoding(),payGateway);//securityCode(安全码)
30. }
31.
32.
33. /**
34. * 根据传入的参数生成alipay的支付URL
35. * @param hm 参数值
36. * @param securityCode 安全码
37. * @param charset 编码
38. * @param payGateway 支付宝gateway
39. * @return
40. */
41. public static String makeUrl(HashMap hm,String securityCode,String charset,String payGateway) throws Exception{
42. List keys = new ArrayList(hm.keySet());
43. Collections.sort(keys);//支付宝要求参数必须按字母排序
44. StringBuffer content = new StringBuffer();
45. for (int i = 0; i < keys.size(); i++) {
46. content.append((String) keys.get(i));
47. content.append(\"=\");
48. content.append((String) hm.get((String) keys.get(i)));
49. if (i != keys.size() - 1) {
50. content.append(\"&\");
51. }
52. }
53. 54. 55. 56. 57. 58. 59. 60. charset)); 61. 62.
content.append(keys.get(i));
content.append(\"=\");
content.append(URLEncoder.encode((String)
content.append(\"&\");
content.append(securityCode); String sign = md5(content.toString(),charset);
content.delete(0,content.length()); content.append(payGateway); for (int i = 0; i < keys.size(); i++) { hm.get(keys.get(i)), } 63. content.append(\"sign=\");
64. content.append(sign);
65. content.append(\"&sign_type=MD5\");
66. keys.clear();
67. keys = null;
68. return content.toString();
69. }
70.
71. /**
72. * 生成md5编码字符串.
73. * @param str 源字符串
74. * @param charset 编码方式
75. * @return
76. *
77. */
78. public static String md5(String str,String charset) {
79. if (str == null)
80. return null;
81. char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
82. 'a', 'b', 'c', 'd', 'e', 'f' };
83.
84. MessageDigest md5MessageDigest = null;
85. byte[] md5Bytes = null;
86. char md5Chars[] = null;
87. byte[] strBytes = null;
88. try {
89. strBytes = str.getBytes(charset);
90. md5MessageDigest = MessageDigest.getInstance(\"MD5\");
91. md5MessageDigest.update(strBytes);
92. md5Bytes = md5MessageDigest.digest();
93. int j = md5Bytes.length;
94. md5Chars = new char[j * 2];
95. int k = 0;
96. for (int i = 0; i < j; i++) {
97. byte md5Byte = md5Bytes[i];
98. md5Chars[k++] = hexDigits[md5Byte >>> 4 & 0xf];
99. md5Chars[k++] = hexDigits[md5Byte & 0xf];
100. }
101. return new String(md5Chars);
102. } catch (NoSuchAlgorithmException e) {
103. //Log.output(e.toString(), Log.STD_ERR);
104. return null;
105. } catch (UnsupportedEncodingException e) {
106. //Log.output(e.toString(), Log.STD_ERR);
107. return null;
108. } finally {
109. md5MessageDigest = null;
110. strBytes = null;
111. md5Bytes = null;
112. }
113. }
114. /**
115. * 根据订单生成支付宝接口URL.
116. * @param httpRequest
117. * @param order 订单实例
118. * @return
119. * @throws Exception
120. */
121. public static String makeOrderAlipayUrl(HttpServletRequest
httpRequest,Order order) throws Exception {
122. HashMap hm = new HashMap();
123. hm.put(\"_input_charset\采用相同的编码方式
124. hm.put(\"body\您在www.xxx.com上的订单\");//填写在跳到支付宝页面上显示的付款内容信息
125. hm.put(\"discount\填写折扣信息 -5表示抵扣5元
126. hm.put(\"logistics_fee\物流费用
127. hm.put(\"logistics_payment\物流费用支付人 BUYER_PAY=买家支付物流费用
128. hm.put(\"logistics_type\物流方式
129. hm.put(\"notify_url\客户付款后,支付宝调用的页面
130. hm.put(\"out_trade_no\外部交易号,最好具有唯一性,在获取支付宝发来的付款信息时使用.
131. hm.put(\"partner\合作伙伴ID)
132. hm.put(\"agent\合作伙伴ID)
133. hm.put(\"payment_type\支付类型 1=商品购买,2=服务购买,...
134. hm.put(\"price\订单金额信息
135. hm.put(\"quantity\订单商品数量,一般都是写1,它是按照整个订单包来计算
136. hm.put(\"return_url\客户付款成功后,显示给客户的页面
137. hm.put(\"seller_email\你的支付宝账户email
138. hm.put(\"service\user=直接付款,trade_create_by_buyer 担保付款
139. hm.put(\"subject\的订单\");//填写在跳到支付宝页面上显示的付款标题信息
140. String payGateway =
\"https://www.alipay.com/cooperate/gateway.do?\";//跳转到支付宝的url头
141. return
makeUrl(hm,securityCode,httpRequest.getCharacterEncoding(),payGateway);//securityCode(安全码)
142. }
143.
144.
145. /**
146. * 根据传入的参数生成alipay的支付URL
147. * @param hm 参数值
148. * @param securityCode 安全码
149. * @param charset 编码
150. * @param payGateway 支付宝gateway
151. * @return
152. */
153. public static String makeUrl(HashMap hm,String securityCode,String charset,String payGateway) throws Exception{
154. List keys = new ArrayList(hm.keySet());
155. Collections.sort(keys);//支付宝要求参数必须按字母排序
156. StringBuffer content = new StringBuffer();
157. for (int i = 0; i < keys.size(); i++) {
158. content.append((String) keys.get(i));
159. content.append(\"=\");
160. content.append((String) hm.get((String) keys.get(i)));
161. if (i != keys.size() - 1) {
162. content.append(\"&\");
163. }
164. }
165. 166. 167. 168. 169. 170. 171. 172. charset));
173. 174.
content.append(keys.get(i));
content.append(\"=\");
content.append(URLEncoder.encode((String) content.append(\"&\");
content.append(securityCode); String sign = md5(content.toString(),charset); content.delete(0,content.length()); content.append(payGateway); for (int i = 0; i < keys.size(); i++) { hm.get(keys.get(i)), } 175. content.append(\"sign=\");
176. content.append(sign);
177. content.append(\"&sign_type=MD5\");
178. keys.clear();
179. keys = null;
180. return content.toString();
181. }
182.
183. /**
184. * 生成md5编码字符串.
185. * @param str 源字符串
186. * @param charset 编码方式
187. * @return
188. *
189. */
190. public static String md5(String str,String charset) {
191. if (str == null)
192. return null;
193. char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
194. 'a', 'b', 'c', 'd', 'e', 'f' };
195.
196. MessageDigest md5MessageDigest = null;
197. byte[] md5Bytes = null;
198. char md5Chars[] = null;
199. byte[] strBytes = null;
200. try {
201. strBytes = str.getBytes(charset);
202. md5MessageDigest = MessageDigest.getInstance(\"MD5\");
203. md5MessageDigest.update(strBytes);
204. md5Bytes = md5MessageDigest.digest();
205. int j = md5Bytes.length;
206. md5Chars = new char[j * 2];
207. int k = 0;
208. for (int i = 0; i < j; i++) {
209. byte md5Byte = md5Bytes[i];
210. md5Chars[k++] = hexDigits[md5Byte >>> 4 & 0xf];
211. md5Chars[k++] = hexDigits[md5Byte & 0xf];
212. }
213. return new String(md5Chars);
214. } catch (NoSuchAlgorithmException e) {
215. //Log.output(e.toString(), Log.STD_ERR);
216. return null;
217.218.219.220.221.222.223.224.225.226.中的url. } catch (UnsupportedEncodingException e) {
//Log.output(e.toString(), Log.STD_ERR);
return null;
} finally {
md5MessageDigest = null;
strBytes = null;
md5Bytes = null;
}
}
当客户通过接口url付款后,支付宝会自动的去调用前面提供的[notify_url]参数
227. (2)支付宝将付款信息返回给系统
228. 当客户付款后,支付宝就会自动调用上面表单提供的[notify_url],下面是一个[notifyurl.jsp]的一个例子:
229. Html代码
230. <%@ page contentType=\"text/html;charset=UTF-8\"%><%@ import=\"com.soft4j.AlipayMgr\"%><%
231. String ret = AlipayMgr.insert(request);
232. if(ret==null){
233. out.print(\"success\");//成功接收支付宝发来的付款信息
234. }else{
235. out.print(\"fail\");//出错
236. }
237. %>
238. <%@ page contentType=\"text/html;charset=UTF-8\"%><%@ import=\"com.soft4j.AlipayMgr\"%><%
page page 239. String ret = AlipayMgr.insert(request);
240. if(ret==null){
241. out.print(\"success\");//成功接收支付宝发来的付款信息
242. }else{
243. out.print(\"fail\");//出错
244. }
245. %>
246. 如果确认收到支付宝发来的客户付款信息,则返回\"success\",这样子支付宝就知道系统已经收到信息了;否则返回\"fail\",这样支付宝会过一段时间后再次发来。其实,只有当支付宝收到\"success\"的返回信息后才会停止发送付款信息,否则会自动的每隔一段时间就调用上面
247. 的[notify_url]通信接口。
248. (3)系统处理支付宝发来的付款信息
249. Java代码
250. /*
251. * Created on 2005-6-12
252. * Author stephen
253. * Email zhoujianqiang AT gmail DOT com
254. * CopyRight(C)2005-2008 , All rights reserved.
255. */
256. package com.soft4j;
257. import java.sql.Connection;
258. import java.sql.SQLException;
259. import java.util.Enumeration;
260. import java.util.Vector;
261. import javax.servlet.http.HttpServletRequest;
262. /**
263. * 支付宝付款通知接口.
264. *
265. * @author stephen
266. * @version 1.0.0
267. */
268. public final class NotifyUrlMgr {
269.
270.
271. public static String insert(HttpServletRequest httpRequest) {
272.
273. //定义变量和进行必要的初始化工作
274. Enumeration parameterNames = null;
275. String parameterName = null;
276. String parameterValue = null;
277. int count = 0;
278. Vector[] params = null;
279. Vector vParameterName = new Vector();
280. Vector vParameterValue = new Vector();
281.
282. try {
283. String orderId = httpRequest.getParameter(\"out_trade_no\");//订单号
284. if(orderId==null||\"\".equals(orderId)) orderId=\"-1\";
285. parameterNames = httpRequest.getParameterNames();
286. boolean isPrint = false;
287. while (parameterNames.hasMoreElements()) {//循环收取支付宝发来的所有参数信息
288. parameterName = (String) parameterNames.nextElement();
289. parameterValue =
httpRequest.getParameter(parameterName);
290. if(parameterValue==null) parameterValue=\"\";
291. vParameterName.add(parameterName);
292. vParameterValue.add(parameterValue);
293. count++;
294. }
295.
296. //这里添加对收到信息的处理:一般是将这些信息存入数据库,然后对客户的订单进行处理.
297.
298. return null;
299. } catch (Exception e) {
300. return e.toString();
301. } finally {
302. //
303. }
304. }
305. }
306. /*
307. * Created on 2005-6-12
308. * Author stephen
309. * Email zhoujianqiang AT gmail DOT com
310. * CopyRight(C)2005-2008 , All rights reserved.
311. */
312. package com.soft4j;
313. import java.sql.Connection;
314. import java.sql.SQLException;
315. import java.util.Enumeration;
316. import java.util.Vector;
317. import javax.servlet.http.HttpServletRequest;
318. /**
319. * 支付宝付款通知接口.
320. *
321. * @author stephen
322. * @version 1.0.0
323. */
324. public final class NotifyUrlMgr {
325.
326.
327. public static String insert(HttpServletRequest httpRequest) {
328.
329. //定义变量和进行必要的初始化工作
330. 331. 332. 333. 334. 335. 336. 337. 338. 339. 号
String orderId = httpRequest.getParameter(\"out_trade_no\");//订单 Enumeration parameterNames = null; String parameterName = null; String parameterValue = null; int count = 0; Vector[] params = null; Vector vParameterName = new Vector(); Vector vParameterValue = new Vector(); try { 340. if(orderId==null||\"\".equals(orderId)) orderId=\"-1\";
341. parameterNames = httpRequest.getParameterNames();
342. boolean isPrint = false;
343. while (parameterNames.hasMoreElements()) {//循环收取支付宝发来的所有参数信息
344. parameterName = (String) parameterNames.nextElement();
345. parameterValue =
httpRequest.getParameter(parameterName);
346. if(parameterValue==null) parameterValue=\"\";
347. vParameterName.add(parameterName);
348. vParameterValue.add(parameterValue);
349. count++;
350. }
351.
352. //这里添加对收到信息的处理:一般是将这些信息存入数据库,然后对客户的订单进行处理.
353.
354. return null;
355. 356. 357. 358. 359. 360. } 361. }
return e.toString();
//
} catch (Exception e) { } finally { }
因篇幅问题不能全部显示,请点此查看更多更全内容