實用乾貨 | 一步一步加你在SpringBoot中集成支付寶電腦網站支付

一:簡介

電腦支付常用於電商和後臺管理系統的賬戶充值等場景。

電腦網站支付 文檔

電腦網站支付流程圖

實用乾貨 | 一步一步加你在SpringBoot中集成支付寶電腦網站支付

二:集成步驟

0. 創建應用、配置密鑰

集成前需要先創建應用、配置密鑰、回調地址等以及alipay-sdk-java.jar和alipay-trade-sdk.jar請查看Spring Boot入門教程(三十五):支付寶集成-準備工作

1. dependency

<code>

<

dependencies

>

<

dependency

>

<

groupId

>

org.springframework.boot

groupId

>

<

artifactId

>

spring-boot-starter-web

artifactId

>

dependency

>

<

dependency

>

<

groupId

>

org.springframework.boot

groupId

>

<

artifactId

>

spring-boot-starter-test

artifactId

>

<

scope

>

test

scope

>

dependency

>

<

dependency

>

<

groupId

>

org.springframework.boot

groupId

>

<

artifactId

>

spring-boot-starter-thymeleaf

artifactId

>

dependency

>

<

dependency

>

<

groupId

>

com.alipay

groupId

>

<

artifactId

>

alipay-sdk-java

artifactId

>

<

version

>

20170725114550

version

>

dependency

>

<

dependency

>

<

groupId

>

com.alipay

groupId

>

<

artifactId

>

alipay-trade-sdk

artifactId

>

<

version

>

20161215

version

>

dependency

>

<

dependency

>

<

groupId

>

com.google.code.gson

groupId

>

<

artifactId

>

gson

artifactId

>

dependency

>

<

dependency

>

<

groupId

>

commons-configuration

groupId

>

<

artifactId

>

commons-configuration

artifactId

>

<

version

>

1.10

version

>

dependency

>

<

dependency

>

<

groupId

>

com.google.zxing

groupId

>

<

artifactId

>

core

artifactId

>

<

version

>

3.2.1

version

>

dependency

>

<

dependency

>

<

groupId

>

org.projectlombok

groupId

>

<

artifactId

>

lombok

artifactId

>

dependency

>

dependencies

>

/<code>

2. application.yml

<code> 

pay:

alipay:

gatewayUrl:

https://openapi.alipaydev.com/gateway.do

appid:

2016091400508498

appPrivateKey:

MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtXKWs+trRSuCxEUvlsEeSAuLWs3B/Dh74R8223BnfzoA29aGeoycAqfKlBMcbzU2G1KayESvZKGpwBLeejSbecRYjgZsQDyEaDimQQJtGFvZVV6u4XNnvIJ72eQzEaEIQfuiorjBTLm6DQuds4R0GxftqON6QFoIZkWB9ZrZKd02cuy16dW+UqtLVGGAHcCIAkB63zUiKSNfweMddneZ7MVs3lvu3xhMnD+5us/+n2Vp4qhfmpYLcdqIW6InU4GypeoOpyUTrfUGpgdR0l924vHy/GQJZEKFaRcK3cYK+ECyKpSIoqaJJFLHbkqsliuPpMUG+rM3jiqeIAH4psAznAgMBAAECggEBAJ5jyEbbxrJzrAh7GhHX1fwUQPYSadTbrPYAfHX2cHlnrQMJtsk+nTLhEv0r+VJwZ8WpYkfMong8kcqYtL7ajcmsHqMAFhE9EWxBxj2ymWsXLabZe93sj30IG9Rq0nxcGQgDO0RqKWLGSFgK93Al2KRInKT3InkY53K+vR61ihVLmGf7+GwPtIZteBy+tuAyvcj2RlkYvjiFi3ySyZ1wA3sJIlgrGiixd6fj20XFGNE3CnAwu0BJgXXbP/S9J4C0RRa3ZXj8fX7oONhVxz2xKxn7AT4e8OWjt7J41H2LRct8Fgl9pqgz2FJYv/WfbkG8x9fGiKYYvPXoxjjrk/tkewkCgYEA8f9Lcu5JPrE9rpw9zlwhm5cOO81xLxdwL5R5/1bRP48BZGIYuqlCbVvjJVqtO8eTnLhUwH7fG8B7cmoeO9bGr9GQrtfyCqz6FtVymTBieJlfgZDVhtzyv2qKOBMIFE8jsbSBK/NHHMvykJ+XdQ1riwCeQDdXICRuYTTFwGk2OsUCgYEAt2SoN95tVmVrvKG6ATLNEtge/ozeVywA4GjltrSw/G9vqp+DkkT2pY19uROuzMazoTzKWpPho2q/qzNlv/ANbOFM2GEmKamQ7CO88JgRxMsPTvc/HxCLU/ClMJU8LcOf9LfP2KYZpPwuheKJoF4vDGj8NsbFmccJyYSdpkNEk7sCgYBJlL2FMaz1sgC2Ue19DIhvfaunRV1P20mSPgwmNmijccETm7w3LXX0OIdFeV/JGHLqqSWj7i+6iXk/ncKZoUGCfi8G6sQ+uL/GJ5qTt6GJV+ExTS+PtSjeSO/EAw1m13Vb+C16hpstx1l23f+4aJ81gbecgPct38XsKpaiXZtOnQKBgQCMsN7QRYYxwoq9YoDUzIlAzKYyeBVWYL6najHYUZR5hG/xQIBqZRem9/4cTvpJxKInrwA6LrrqaEl0aHDFp75U6h7O3PCvA5PXZK9dD/yJsZIj7U/yX/nTQokn1UUegrYiwiTkusBvrrtuINWePsLvTVc4GpObHnPmsiNTWsWwYwKBgENaeTNOCHV2km/ysXQSEIhKbtlAMQPsgWHCt/bzHlF9m18izb1LrJyjzcSsd+Zy78R+pv4G50Q27c3e/DFPz/wYxN/yHWRbyLBA8ipJbCtMtPEdS9krpmN6cChIdLGbz4CVUqOPSRzNb9lhhgPCcCNRq6DG3HBceb1Se9VnO3zk

alipayPublicKey:

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApFQKccMq+wPoWh93DcX3XYrnT7FJ3gntJA/jEwgk6Jd3iEVS2CyUCCgFVcQn8xjXT81YbZHYvoC50IBuu+A+Ey+J8VIgsBm5g9uwbOLRf66GrZjuKOlalHm5gHXjcL2gZRMBJEStOxstcO2YQriqhQzdL3EKp+HQc9u14IOVFpZdR8qq1l7CzKHn1vQo/1fUPfUrTLQqSuQTU9Ospv/QHFqOJA7DPetUQ+jnaZ082f3clr4ITw4EE8A6IWqTXcETTx5j/udCGP84g2Y4j+8i9DqYGyD5ePVgt4G0ICBX1bi1qNlylfxRg8Y3c1DFrRGyr0NpKQxSVXkYaVNvrCoudQIDAQAB

returnUrl:

http://s9v2cw.natappfree.cc/alipay/return

notifyUrl:

http://s9v2cw.natappfree.cc/alipay/notify

spring:

thymeleaf:

prefix:

classpath:/templates/

suffix:

.html

mode:

HTML5

encoding:

UTF-8

/<code>

3. AlipayProperties

<code> 
 
 
 (prefix = 

"pay.alipay"

)

public

class

AlipayProperties {

private

String

gatewayUrl;

private

String

appid;

private

String

appPrivateKey;

private

String

alipayPublicKey;

private

String

signType =

"RSA2"

;

private

String

formate =

"json"

;

private

String

charset =

"UTF-8"

;

private

String

returnUrl;

private

String

notifyUrl;

private

static

int maxQueryRetry =

5

;

private

static

long queryDuration =

5000

;

private

static

int maxCancelRetry =

3

;

private

static

long cancelDuration =

3000

;

private

AlipayProperties() {}

public

void

init() { log.info(description()); }

public

String

description() { StringBuilder sb =

new

StringBuilder(

"\nConfigs{"

); sb.append(

"支付寶網關: "

).append(gatewayUrl).append(

"\n"

); sb.append(

", appid: "

).append(appid).append(

"\n"

); sb.append(

", 商戶RSA私鑰: "

).append(getKeyDescription(appPrivateKey)).append(

"\n"

); sb.append(

", 支付寶RSA公鑰: "

).append(getKeyDescription(alipayPublicKey)).append(

"\n"

); sb.append(

", 簽名類型: "

).append(signType).append(

"\n"

); sb.append(

", 查詢重試次數: "

).append(maxQueryRetry).append(

"\n"

); sb.append(

", 查詢間隔(毫秒): "

).append(queryDuration).append(

"\n"

); sb.append(

", 撤銷嘗試次數: "

).append(maxCancelRetry).append(

"\n"

); sb.append(

", 撤銷重試間隔(毫秒): "

).append(cancelDuration).append(

"\n"

); sb.append(

"}"

);

return

sb.toString(); }

private

String

getKeyDescription(

String

key) { int showLength =

6

;

if

(StringUtils.isNotEmpty(key) && key.length() > showLength) {

return

new

StringBuilder(key.substring(

0

, showLength)).append(

"******"

) .append(key.substring(key.length() - showLength)).toString(); }

return

null

; } } /<code>

4. AlipayConfiguration

<code> 

@Configuration

@EnableConfigurationProperties(AlipayProperties.class) public class AlipayConfiguration {

@Autowired

private AlipayProperties properties;

@Bean

public AlipayTradeService alipayTradeService() {

return

new

AlipayTradeServiceImpl

.ClientBuilder

()

.setGatewayUrl

(

properties

.getGatewayUrl

())

.setAppid

(

properties

.getAppid

())

.setPrivateKey

(

properties

.getAppPrivateKey

())

.setAlipayPublicKey

(

properties

.getAlipayPublicKey

())

.setSignType

(

properties

.getSignType

())

.build

(); }

@Bean

public AlipayClient alipayClient(){

return

new

DefaultAlipayClient

(

properties

.getGatewayUrl

(),

properties

.getAppid

(),

properties

.getAppPrivateKey

(),

properties

.getFormate

(),

properties

.getCharset

(),

properties

.getAlipayPublicKey

(),

properties

.getSignType

()); } } /<code>

5. AlipayPagePayController

<code> 
 
 (

"/alipay/page"

)

public

class

AlipayPagePayController

{

private

AlipayProperties alipayProperties;

private

AlipayClient alipayClient;

private

AlipayController alipayController; (

"/gotoPayPage"

)

public

void

gotoPayPage

(HttpServletResponse response)

throws

AlipayApiException, IOException

{ String productCode =

"FAST_INSTANT_TRADE_PAY"

; AlipayTradePagePayModel model =

new

AlipayTradePagePayModel(); model.setOutTradeNo(UUID.randomUUID().toString()); model.setSubject(

"支付測試"

); model.setTotalAmount(

"0.01"

); model.setBody(

"支付測試,共0.01元"

); model.setProductCode(productCode); AlipayTradePagePayRequest pagePayRequest =

new

AlipayTradePagePayRequest(); pagePayRequest.setReturnUrl(

"http://s9v2cw.natappfree.cc/alipay/page/returnUrl"

); pagePayRequest.setNotifyUrl(alipayProperties.getNotifyUrl()); pagePayRequest.setBizModel(model); String form = alipayClient.pageExecute(pagePayRequest).getBody(); response.setContentType(

"text/html;charset="

+ alipayProperties.getCharset()); response.getWriter().write(form); response.getWriter().flush(); response.getWriter().close(); } (

"/returnUrl"

)

public

String

returnUrl

(HttpServletRequest request, HttpServletResponse response)

throws

UnsupportedEncodingException, AlipayApiException

{ response.setContentType(

"text/html;charset="

+ alipayProperties.getCharset());

boolean

verifyResult = alipayController.rsaCheckV1(request);

if

(verifyResult){ String out_trade_no =

new

String(request.getParameter(

"out_trade_no"

).getBytes(

"ISO-8859-1"

),

"UTF-8"

); String trade_no =

new

String(request.getParameter(

"trade_no"

).getBytes(

"ISO-8859-1"

),

"UTF-8"

);

return

"pagePaySuccess"

; }

else

{

return

"pagePayFail"

; } } } /<code>

6. AlipayController

<code> 
 
 
 (

"/alipay"

)

public

class

AlipayController {

private

AlipayProperties aliPayProperties;

private

AlipayClient alipayClient;

private

AlipayTradeService alipayTradeService; (

"/notify"

)

public

String

notify(HttpServletRequest request) throws AlipayApiException, UnsupportedEncodingException { Map<

String

,

String

[]> parameterMap = request.getParameterMap(); StringBuilder notifyBuild =

new

StringBuilder(

"/****************************** alipay notify ******************************/\n"

); parameterMap.forEach((key, value) -> notifyBuild.append(key +

"="

+ value[

0

] +

"\n"

) ); log.info(notifyBuild.toString());

boolean

flag =

this

.rsaCheckV1(request);

if

(flag) {

String

tradeStatus =

new

String

(request.getParameter(

"trade_status"

).getBytes(

"ISO-8859-1"

),

"UTF-8"

);

String

out_trade_no =

new

String

(request.getParameter(

"out_trade_no"

).getBytes(

"ISO-8859-1"

),

"UTF-8"

);

String

trade_no =

new

String

(request.getParameter(

"trade_no"

).getBytes(

"ISO-8859-1"

),

"UTF-8"

);

String

total_amount =

new

String

(request.getParameter(

"total_amount"

).getBytes(

"ISO-8859-1"

),

"UTF-8"

);

if

(tradeStatus.equals(

"TRADE_FINISHED"

)){ }

else

if

(tradeStatus.equals(

"TRADE_SUCCESS"

)){ }

return

"success"

; }

return

"fail"

; } (

"/query"

)

public

String

query(

String

orderNo){ AlipayTradeQueryRequestBuilder builder =

new

AlipayTradeQueryRequestBuilder() .setOutTradeNo(orderNo); AlipayF2FQueryResult result = alipayTradeService.queryTradeResult(builder);

switch

(result.getTradeStatus()) {

case

SUCCESS: log.info(

"查詢返回該訂單支付成功: )"

); AlipayTradeQueryResponse resp = result.getResponse(); log.info(resp.getTradeStatus());

break

;

case

FAILED: log.error(

"查詢返回該訂單支付失敗!!!"

);

break

;

case

UNKNOWN: log.error(

"系統異常,訂單支付狀態未知!!!"

);

break

;

default

: log.error(

"不支持的交易狀態,交易返回異常!!!"

);

break

; }

return

result.getResponse().getBody(); } (

"/refund"

)

public

String

refund(

String

orderNo) throws AlipayApiException { AlipayTradeRefundRequest alipayRequest =

new

AlipayTradeRefundRequest(); AlipayTradeRefundModel model=

new

AlipayTradeRefundModel(); model.setOutTradeNo(orderNo); model.setRefundAmount(

"0.01"

); model.setRefundReason(

"無理由退貨"

); alipayRequest.setBizModel(model); AlipayTradeRefundResponse alipayResponse = alipayClient.execute(alipayRequest); System.out.println(alipayResponse.getBody());

return

alipayResponse.getBody(); } (

"/refundQuery"

)

public

String

refundQuery(

String

orderNo,

String

refundOrderNo) throws AlipayApiException { AlipayTradeFastpayRefundQueryRequest alipayRequest =

new

AlipayTradeFastpayRefundQueryRequest(); AlipayTradeFastpayRefundQueryModel model=

new

AlipayTradeFastpayRefundQueryModel(); model.setOutTradeNo(orderNo); model.setOutRequestNo(refundOrderNo); alipayRequest.setBizModel(model); AlipayTradeFastpayRefundQueryResponse alipayResponse = alipayClient.execute(alipayRequest); System.out.println(alipayResponse.getBody());

return

alipayResponse.getBody(); } (

"/close"

)

public

String

close(

String

orderNo) throws AlipayApiException { AlipayTradeCloseRequest alipayRequest =

new

AlipayTradeCloseRequest(); AlipayTradeCloseModel model =

new

AlipayTradeCloseModel(); model.setOutTradeNo(orderNo); alipayRequest.setBizModel(model); AlipayTradeCloseResponse alipayResponse = alipayClient.execute(alipayRequest); System.out.println(alipayResponse.getBody());

return

alipayResponse.getBody(); }

public

boolean

rsaCheckV1(HttpServletRequest request){ Map<

String

,

String

> params =

new

HashMap<>(); Map requestParams = request.getParameterMap();

for

(Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {

String

name = (

String

) iter.next();

String

[] values = (

String

[]) requestParams.get(name);

String

valueStr =

""

;

for

(int i =

0

; i < values.length; i++) { valueStr = (i == values.length -

1

) ? valueStr + values[i] : valueStr + values[i] +

","

; } params.put(name, valueStr); }

try

{

boolean

verifyResult = AlipaySignature.rsaCheckV1(params, aliPayProperties.getAlipayPublicKey(), aliPayProperties.getCharset(), aliPayProperties.getSignType());

return

verifyResult; }

catch

(AlipayApiException e) { log.debug(

"verify sigin error, exception is:{}"

, e);

return

false

; } } } /<code>

7. WebMvcConfiguration

<code> 
 

public

class

WebMvcConfiguration

extends

WebMvcConfigurationSupport

{

protected

void

addViewControllers

(ViewControllerRegistry registry)

{ registry.addViewController(

"/gotoWapPage"

).setViewName(

"gotoWapPay"

); registry.addViewController(

"/gotoPagePage"

).setViewName(

"gotoPagePay"

);

super

.addViewControllers(registry); } } /<code>

8. templates

gotoPagePay.html

<code> >

<

html

lang

=

"en"

>

<

head

>

<

meta

charset

=

"UTF-8"

>

<

title

>

Title

title

>

head

>

<

body

style

=

"font-size: 30px"

>

<

form

method

=

"post"

action

=

"/alipay/page/gotoPayPage"

>

<

h3

>

購買商品:越南新娘

h3

>

<

h3

>

價格:20000

h3

>

<

h3

>

數量:10個

h3

>

<

button

style

=

"width: 100%; height: 60px; alignment: center; background: #b49e8f"

type

=

"submit"

>

立即支付

button

>

form

>

body

>

html

>

/<code>

pagePaySuccess.html

<code> >

<

html

lang

=

"en"

>

<

head

>

<

meta

charset

=

"UTF-8"

>

<

title

>

Title

title

>

head

>

<

body

>

<

h1

>

電腦網站支付 成功,我們將盡快從越南偷渡過來,收貨後請請及時驗貨!歡迎下次再來

h1

>

body

>

html

>

/<code>

三:Demo圖

實用乾貨 | 一步一步加你在SpringBoot中集成支付寶電腦網站支付

實用乾貨 | 一步一步加你在SpringBoot中集成支付寶電腦網站支付

實用乾貨 | 一步一步加你在SpringBoot中集成支付寶電腦網站支付

實用乾貨 | 一步一步加你在SpringBoot中集成支付寶電腦網站支付

實用乾貨 | 一步一步加你在SpringBoot中集成支付寶電腦網站支付

實用乾貨 | 一步一步加你在SpringBoot中集成支付寶電腦網站支付

三:查詢對賬單下載地址

<code> 
 (

"/bill"

)

public

void

queryBill(

String

billDate) { AlipayDataDataserviceBillDownloadurlQueryRequest request =

new

AlipayDataDataserviceBillDownloadurlQueryRequest(); AlipayDataDataserviceBillDownloadurlQueryModel model =

new

AlipayDataDataserviceBillDownloadurlQueryModel(); model.setBillType(

"trade"

); model.setBillDate(billDate); request.setBizModel(model);

try

{ AlipayDataDataserviceBillDownloadurlQueryResponse response = alipayClient.execute(request);

if

(response.isSuccess()) {

String

billDownloadUrl = response.getBillDownloadUrl(); System.out.println(billDownloadUrl); List<

String

> orderList =

this

.downloadBill(billDownloadUrl); System.out.println(orderList); }

else

{

String

code = response.getCode();

String

msg = response.getMsg();

String

subCode = response.getSubCode();

String

subMsg = response.getSubMsg(); } }

catch

(AlipayApiException e) { e.printStackTrace(); }

catch

(IOException e) { e.printStackTrace(); } }

private

List<

String

> downloadBill(

String

billDownLoadUrl) throws IOException {

String

ordersStr =

""

; CloseableHttpClient httpClient = HttpClients.createDefault(); RequestConfig config = RequestConfig.custom() .setConnectTimeout(

60000

) .setConnectionRequestTimeout(

60000

) .setSocketTimeout(

60000

) .build(); HttpGet httpRequest =

new

HttpGet(billDownLoadUrl); httpRequest.setConfig(config); CloseableHttpResponse response =

null

; byte[] data =

null

;

try

{ response = httpClient.execute(httpRequest); HttpEntity entity = response.getEntity(); data = EntityUtils.toByteArray(entity); }

finally

{ response.close(); httpClient.close(); } ZipInputStream zipInputStream =

new

ZipInputStream(

new

ByteArrayInputStream(data), Charset.forName(

"GBK"

)); ZipEntry zipEntry =

null

;

try

{

while

( (zipEntry = zipInputStream.getNextEntry()) !=

null

){ ByteArrayOutputStream byteArrayOutputStream =

new

ByteArrayOutputStream();

try

{

String

name = zipEntry.getName();

if

(name.contains(

"彙總"

)){

continue

; } byte[] byteBuff =

new

byte[

4096

]; int bytesRead =

0

;

while

((bytesRead = zipInputStream.read(byteBuff)) !=

-1

) { byteArrayOutputStream.write(byteBuff,

0

, bytesRead); } ordersStr = byteArrayOutputStream.toString(

"GBK"

); }

finally

{ byteArrayOutputStream.close(); zipInputStream.closeEntry(); } } }

finally

{ zipInputStream.close(); }

if

(ordersStr.equals(

""

)) {

return

null

; }

String

[] bills = ordersStr.split(

"\r\n"

); List<

String

> billList = Arrays.asList(bills); billList = billList.parallelStream().map(item -> item.replace(

"\t"

,

""

)).collect(Collectors.toList());

return

billList; } /<code>
實用乾貨 | 一步一步加你在SpringBoot中集成支付寶電腦網站支付

實用乾貨 | 一步一步加你在SpringBoot中集成支付寶電腦網站支付

實用乾貨 | 一步一步加你在SpringBoot中集成支付寶電腦網站支付


分享到:


相關文章: