Merge remote-tracking branch 'origin/develop' into develop

master
dalong306 3 years ago
commit c81da8900a

@ -865,13 +865,13 @@ paths:
code_url: code_url:
type: string type: string
description: 付款码字符串,商户可自行生成二维码 # todo description: 付款码字符串,商户可自行生成二维码 # todo
/alipay/partners/{partner_code}/orders/{partner_order_id}: /web_gateway/partners/{partner_code}/orders/{partner_order_id}:
put: put:
summary: 渠道网关订单下单 summary: 渠道网关订单下单
x-sort-order: 0 x-sort-order: 0
description: | description: |
创建订单后跳转到返回的pay_url需附加签名参数和redirect参数随后进入支付宝支付页面完成支付 创建订单后跳转到返回的pay_url需附加签名参数和redirect参数随后进入渠道网关支付页面完成支付
该接口现仅支持支付宝 该接口现仅支持支付宝和Alipay+
tags: tags:
- ChannelGateway - ChannelGateway
parameters: parameters:

@ -51,6 +51,7 @@ orderWithChannel:
enum: enum:
- Alipay - Alipay
- Wechat - Wechat
- AlipayPlus
type: object type: object
required: required:
- channel - channel

@ -145,10 +145,10 @@ tags:
Retail payment API for merchants has their own machine. Has 2 modes: Retail payment API for merchants has their own machine. Has 2 modes:
- Merchant scanner scan customer provided payment code.(B scan C) - Merchant scanner scan customer provided payment code.(B scan C)
- Customer scan merchant provided collection code. (C scan B) - Customer scan merchant provided collection code. (C scan B)
- name: AlipayOnline - name: ChannelGateway
description: | description: |
Use for Alipay Payment in PC Website. After create order, jump to the pay_url returned and attach sign params and redirect param. Then enter Alipay page to finish payment. Use for Channel Cashier Payment in PC Website. After create order, jump to the pay_url returned and attach sign params and redirect param. Then enter Channel cashier page to finish payment.
Alipay Channel only Alipay and AlipayPlus Channels only
<img src="img/alipayOnline_en.png"> <img src="img/alipayOnline_en.png">
- name: CB Bank - name: CB Bank
description: | description: |
@ -260,7 +260,7 @@ paths:
- SDK Payment - SDK Payment
- CB Bank - CB Bank
- RetailPay - RetailPay
- AlipayOnline - ChannelGateway
- CardPayment - CardPayment
- MiniProgram - MiniProgram
- MobileH5 - MobileH5
@ -288,7 +288,7 @@ paths:
- SDK Payment - SDK Payment
- CB Bank - CB Bank
- RetailPay - RetailPay
- AlipayOnline - ChannelGateway
- CardPayment - CardPayment
- MiniProgram - MiniProgram
- MobileH5 - MobileH5
@ -888,14 +888,14 @@ paths:
code_url: code_url:
type: string type: string
description: QR Code string. Partners can create the payment QR Code according to this value. description: QR Code string. Partners can create the payment QR Code according to this value.
/alipay/partners/{partner_code}/orders/{partner_order_id}: /web_gateway/partners/{partner_code}/orders/{partner_order_id}:
put: put:
summary: Alipay WEB Order summary: Channel WEB Order
description: | description: |
Use for Alipay Payment in PC Website. After create order, jump to the pay_url returned and attach sign params and redirect param. Then enter Alipay page to finish payment. Use for Channel Payment Cashier in PC Website. After create order, jump to the pay_url returned and attach sign params and redirect param. Then enter Channel cashier page to finish payment.
Alipay Channel Only. Alipay and AlipayPlus only at the moment.
tags: tags:
- AlipayOnline - ChannelGateway
parameters: parameters:
- name: partner_code - name: partner_code
in: path in: path
@ -1106,7 +1106,7 @@ paths:
- MobileH5 - MobileH5
- MiniProgram - MiniProgram
- CardPayment - CardPayment
- AlipayOnline - ChannelGateway
- RetailPay - RetailPay
- CB Bank - CB Bank
- SDK Payment - SDK Payment
@ -1151,7 +1151,7 @@ paths:
- MobileH5 - MobileH5
- MiniProgram - MiniProgram
- CardPayment - CardPayment
- AlipayOnline - ChannelGateway
- RetailPay - RetailPay
- CB Bank - CB Bank
- SDK Payment - SDK Payment
@ -1331,7 +1331,7 @@ paths:
- SDK Payment - SDK Payment
- CB Bank - CB Bank
- RetailPay - RetailPay
- AlipayOnline - ChannelGateway
- CardPayment - CardPayment
- MiniProgram - MiniProgram
- MobileH5 - MobileH5
@ -1376,7 +1376,7 @@ paths:
description: Currency, AUD description: Currency, AUD
channel: channel:
type: string type: string
description: Payment Channel Alipay, AlipayOnline, Wechat description: Payment Channel Alipay, AlipayOnline, Wechat, AlipayPlus
create_time: create_time:
type: string type: string
format: 'date-time' format: 'date-time'

@ -56,6 +56,8 @@ public interface CleanService {
void settlementAba(Date date, HttpServletResponse response) throws IOException; void settlementAba(Date date, HttpServletResponse response) throws IOException;
List<JSONObject> getCustomizedSettleDaily(Date date);
void getCustomizedSettleABA(int logId, HttpServletResponse response); void getCustomizedSettleABA(int logId, HttpServletResponse response);
void getSettlementFilesForBatch(String batchId, HttpServletResponse resp) throws IOException; void getSettlementFilesForBatch(String batchId, HttpServletResponse resp) throws IOException;

@ -668,6 +668,15 @@ public class CleanServiceImpl implements CleanService, ManagerTodoNoticeProvider
} }
} }
@Override
public List<JSONObject> getCustomizedSettleDaily(Date date) {
DateTime dtFrom = new DateTime(date);
DateTime dtTo = dtFrom.plusDays(1);
List<JSONObject> logs = customizedSettleLogMapper.listByDate(dtFrom.toDate(), dtTo.toDate());
logs.forEach(log -> log.put("aba_file", String.format("/sys/settlement/customized_settle/%s/aba_file", log.getIntValue("log_id"))));
return logs;
}
@Override @Override
public void getCustomizedSettleABA(int logId, HttpServletResponse response) { public void getCustomizedSettleABA(int logId, HttpServletResponse response) {
JSONObject log = customizedSettleLogMapper.find(logId); JSONObject log = customizedSettleLogMapper.find(logId);
@ -686,7 +695,8 @@ public class CleanServiceImpl implements CleanService, ManagerTodoNoticeProvider
settle.put("client_moniker", log.getString("client_moniker")); settle.put("client_moniker", log.getString("client_moniker"));
ABAFile file = generateSettleAbaFile(bank, group, new Date(), Collections.singletonList(settle)); ABAFile file = generateSettleAbaFile(bank, group, new Date(), Collections.singletonList(settle));
response.setContentType("application/octet-stream;"); response.setContentType("application/octet-stream;");
response.addHeader("Content-Disposition", "attachment; filename=" + file.filename()); String filename = String.format("[%s]Manual_Settle_%s_%s.aba", logId, log.getString("client_moniker"), DateTime.now().toString("yyyyMMdd"));
response.addHeader("Content-Disposition", "attachment; filename=" + filename);
try (OutputStream ous = response.getOutputStream()) { try (OutputStream ous = response.getOutputStream()) {
ous.write(file.output(1)); ous.write(file.output(1));
ous.flush(); ous.flush();

@ -9,6 +9,7 @@ import au.com.royalpay.payment.tools.exceptions.BadRequestException;
import au.com.royalpay.payment.tools.merchants.beans.BalanceGroup; import au.com.royalpay.payment.tools.merchants.beans.BalanceGroup;
import au.com.royalpay.payment.tools.permission.enums.ManagerRole; import au.com.royalpay.payment.tools.permission.enums.ManagerRole;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import org.joda.time.DateTime;
import org.springframework.core.io.ByteArrayResource; import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
@ -170,6 +171,12 @@ public class SettlementDevController {
} }
} }
@GetMapping("/customized_settle/dates/{date}")
public List<JSONObject> customizedSettleInDay(@PathVariable String date){
Date dt = DateTime.parse(date).withTimeAtStartOfDay().toDate();
return cleanService.getCustomizedSettleDaily(dt);
}
@GetMapping("/customized_settle/{logId}/aba_file") @GetMapping("/customized_settle/{logId}/aba_file")
public void getCustomizedSettleABAFile(@PathVariable int logId,HttpServletResponse response){ public void getCustomizedSettleABAFile(@PathVariable int logId,HttpServletResponse response){
cleanService.getCustomizedSettleABA(logId, response); cleanService.getCustomizedSettleABA(logId, response);

@ -5,10 +5,17 @@ import com.yixsoft.support.mybatis.autosql.annotations.AutoMapper;
import com.yixsoft.support.mybatis.autosql.annotations.AutoSql; import com.yixsoft.support.mybatis.autosql.annotations.AutoSql;
import com.yixsoft.support.mybatis.autosql.annotations.SqlType; import com.yixsoft.support.mybatis.autosql.annotations.SqlType;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator; import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator;
import java.util.Date;
import java.util.List;
@AutoMapper(tablename = "log_settle_customized", pkName = "log_id", keyGenerator = Jdbc3KeyGenerator.class) @AutoMapper(tablename = "log_settle_customized", pkName = "log_id", keyGenerator = Jdbc3KeyGenerator.class)
public interface CustomizedSettleLogMapper { public interface CustomizedSettleLogMapper {
@AutoSql(SqlType.SELECT) @AutoSql(SqlType.SELECT)
JSONObject find(@Param("log_id") int logId); JSONObject find(@Param("log_id") int logId);
@Select("select * from log_settle_customized where create_time between #{date_from} and #{date_to}")
List<JSONObject> listByDate(@Param("date_from") Date dateFrom,@Param("date_to") Date dateTo);
} }

@ -2705,16 +2705,27 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid
public void writeAggregatePoster(JSONObject manager, String clientMoniker, OutputStream ous) { public void writeAggregatePoster(JSONObject manager, String clientMoniker, OutputStream ous) {
JSONObject client = clientDetail(manager, clientMoniker); JSONObject client = clientDetail(manager, clientMoniker);
try { try {
logger.debug("downloading aggregate poster from {}", clientMoniker); String url = PlatformEnvironment.getEnv().concatUrl("/static/images/new_aggregate_poster.png");
logger.debug("downloading aggregate poster from {}--{}", clientMoniker, url);
HttpRequestResult boardBackgroundResult = new HttpRequestGenerator( HttpRequestResult boardBackgroundResult = new HttpRequestGenerator(
PlatformEnvironment.getEnv().concatUrl("/static/images/new_aggregate_poster.png"), RequestMethod.GET).execute(); url, RequestMethod.GET).execute();
if (boardBackgroundResult.isSuccess()) { if (boardBackgroundResult.isSuccess()) {
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
InputStream ins = boardBackgroundResult.getResponseContentStream(); InputStream ins = boardBackgroundResult.getResponseContentStream();
BufferedImage background = ImageIO.read(ins); BufferedImage background = ImageIO.read(ins);
IOUtils.closeQuietly(ins); IOUtils.closeQuietly(ins);
ImageIO.write(background, "jpeg", ous); logger.debug("aggregate image size {}x{}", background.getWidth(), background.getHeight());
ous.flush(); BufferedImage img = new BufferedImage(background.getWidth(), background.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
Graphics g = img.getGraphics();
g.drawImage(background, 0, 0, null);
g.dispose();
ImageIO.write(img, "jpeg", bos);
bos.flush();
byte[] imageBytes = bos.toByteArray();
logger.debug("aggregate image length {}", imageBytes.length);
ous.write(imageBytes);
IOUtils.closeQuietly(ous); IOUtils.closeQuietly(ous);
}
} else { } else {
logger.error("get aggregate poster file failed:[{}]-{}", boardBackgroundResult.getStatusCode(), logger.error("get aggregate poster file failed:[{}]-{}", boardBackgroundResult.getStatusCode(),
boardBackgroundResult.getResponseContentString(), boardBackgroundResult.getException()); boardBackgroundResult.getResponseContentString(), boardBackgroundResult.getException());

@ -12,23 +12,20 @@ public class ShopifyRequestValidator {
private String clientSecret; private String clientSecret;
public Boolean valid(ShopifyCommonParameter parameter) { public Boolean valid(ShopifyCommonParameter parameter) {
StringBuilder message =new StringBuilder(); StringBuilder message = new StringBuilder();
message.append("code=").append(parameter.getCode()) message.append("code=").append(parameter.getCode())
.append("&host=").append(parameter.getHost()) .append("&host=").append(parameter.getHost())
.append("&shop=").append(parameter.getShop()) .append("&shop=").append(parameter.getShop())
.append("&state=").append(parameter.getState()) .append("&state=").append(parameter.getState())
.append("&timestamp=").append(parameter.getTimestamp()); .append("&timestamp=").append(parameter.getTimestamp());
return HmacVerificationUtil.hmacSHA256(message.toString(),clientSecret,parameter.getHmac()); return HmacVerificationUtil.hmacSHA256(message.toString(), clientSecret, parameter.getHmac());
} }
public boolean verifyPermission(String shopifyStoreHost, String hmac, String timestamp) { public boolean verifyPermission(String queryStrWithoutHmac, String hmac) {
StringBuilder message =new StringBuilder(); return HmacVerificationUtil.hmacSHA256(queryStrWithoutHmac, clientSecret, hmac);
message.append("shop=").append(shopifyStoreHost)
.append("&timestamp=").append(timestamp);
return HmacVerificationUtil.hmacSHA256(message.toString(),clientSecret,hmac);
} }
public boolean verify(String message, String hmac) { public boolean verify(String message, String hmac) {
return HmacVerificationUtil.hmacSHA256(message,clientSecret,hmac); return HmacVerificationUtil.hmacSHA256(message, clientSecret, hmac);
} }
} }

@ -10,9 +10,12 @@ import au.com.royalpay.payment.tools.env.PlatformEnvironment;
import au.com.royalpay.payment.tools.exceptions.BadRequestException; import au.com.royalpay.payment.tools.exceptions.BadRequestException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.util.UriComponentsBuilder;
import javax.servlet.http.HttpServletRequest;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@Controller @Controller
@ -33,18 +36,18 @@ public class ShopifyAuthTemplateController {
* *
* @param shop * @param shop
* @param hmac * @param hmac
* @param timestamp
* @return * @return
*/ */
@GetMapping("/auth") @GetMapping("/auth")
@ShopifyEndpoint @ShopifyEndpoint
public String shopifyStorePermission(@RequestParam("shop") String shop, public String shopifyStorePermission(@RequestParam("shop") String shop,
@RequestParam("hmac") String hmac, @RequestParam("hmac") String hmac, HttpServletRequest request) {
@RequestParam("timestamp") String timestamp) {
if (!Pattern.matches("^[a-zA-Z0-9][a-zA-Z0-9\\-]*\\.myshopify\\.com", shop)) { if (!Pattern.matches("^[a-zA-Z0-9][a-zA-Z0-9\\-]*\\.myshopify\\.com", shop)) {
throw new BadRequestException("Parameter shop is invalid."); throw new BadRequestException("Parameter shop is invalid.");
} }
if (!shopifyRequestValidator.verifyPermission(shop, hmac, timestamp)) { String queryStr = UriComponentsBuilder.fromHttpRequest(new ServletServerHttpRequest(request))
.replaceQueryParam("hmac").build().getQuery();
if (!shopifyRequestValidator.verifyPermission(queryStr, hmac)) {
throw new ShopifyRequestVerifyException("This request parameters is invalid"); throw new ShopifyRequestVerifyException("This request parameters is invalid");
} }
ShopifyPermissionURL shopifyPermissionURL = shopifyMerchantAuthApplication.getShopifyPermissionUrl(shop); ShopifyPermissionURL shopifyPermissionURL = shopifyMerchantAuthApplication.getShopifyPermissionUrl(shop);

@ -5,6 +5,8 @@ import org.apache.commons.codec.digest.HmacUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.crypto.RuntimeCryptoException; import org.bouncycastle.crypto.RuntimeCryptoException;
import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.crypto.Mac; import javax.crypto.Mac;
import javax.crypto.SecretKey; import javax.crypto.SecretKey;
@ -15,6 +17,10 @@ import java.security.Security;
import java.util.Locale; import java.util.Locale;
public class HmacVerificationUtil { public class HmacVerificationUtil {
private static final Logger logger = LoggerFactory.getLogger(HmacVerificationUtil.class);
private HmacVerificationUtil() {
}
public static boolean checkParameters(String message, String secret, String hmac) { public static boolean checkParameters(String message, String secret, String hmac) {
try { try {
@ -32,6 +38,7 @@ public class HmacVerificationUtil {
public static boolean hmacSHA256(String input, String key, String hmac) { public static boolean hmacSHA256(String input, String key, String hmac) {
String encode = encode(input, key, HmacAlgorithms.HMAC_SHA_256); String encode = encode(input, key, HmacAlgorithms.HMAC_SHA_256);
logger.debug("input={}; key={}; encoded={}; request-hmac: {}", input, key, encode, hmac);
return StringUtils.equals(encode, hmac); return StringUtils.equals(encode, hmac);
} }

@ -15,6 +15,9 @@ public class ShopifyRequestInfoInterceptor extends HandlerInterceptorAdapter {
@Override @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (!(handler instanceof HandlerMethod)){
return super.preHandle(request, response, handler);
}
Method method = ((HandlerMethod) handler).getMethod(); Method method = ((HandlerMethod) handler).getMethod();
if(HttpMethod.GET.matches(request.getMethod())) { if(HttpMethod.GET.matches(request.getMethod())) {

@ -181,7 +181,7 @@ shopify:
auth: auth:
apiKey: 99e631dd0faa1076ceffae36cf91a93b apiKey: 99e631dd0faa1076ceffae36cf91a93b
apiSecretKey: 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 apiSecretKey: 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
scope: write_orders,read_customers,write_payment_gateways,write_payment_sessions scope: write_orders,write_payment_gateways,write_payment_sessions

@ -269,6 +269,18 @@ define(['angular', 'decimal', 'uiBootstrap', 'uiRouter', 'angularEcharts'], func
$state.reload(); $state.reload();
}; };
$scope.showCustomizedSettle = function () {
$uibModal.open({
templateUrl: '/static/analysis/templates/dialog_customized_settle.html',
controller: 'customizedDialogCtrl',
resolve: {
customizedLogs: function () {
return $http.get('/sys/settlement/customized_settle/dates/' + $scope.datePattern)
}
}
})
}
let nowStr = $filter('date')(new Date(), "yyyy-MM-dd"); let nowStr = $filter('date')(new Date(), "yyyy-MM-dd");
$scope.datePattern = $stateParams.date; $scope.datePattern = $stateParams.date;
if ($scope.datePattern == nowStr) { if ($scope.datePattern == nowStr) {
@ -375,6 +387,10 @@ define(['angular', 'decimal', 'uiBootstrap', 'uiRouter', 'angularEcharts'], func
}) })
} }
}]); }]);
app.controller('customizedDialogCtrl', ['$scope', 'customizedLogs', function ($scope, customizedLogs) {
$scope.customizedLogs = customizedLogs.data
}])
app.controller('settlementTransactionsCtrl', ['$scope', '$stateParams', 'detail', function ($scope, $stateParams, detail) { app.controller('settlementTransactionsCtrl', ['$scope', '$stateParams', 'detail', function ($scope, $stateParams, detail) {
$scope.ctrl = {channel: null}; $scope.ctrl = {channel: null};
$scope.report = detail.data; $scope.report = detail.data;

@ -0,0 +1,27 @@
<div class="modal-header">Manual Settlements</div>
<div class="modal-body">
<table class="table table-striped table-bordered table-hover" ng-if="customizedLogs.length">
<thead>
<tr>
<th>Merchant</th>
<th>Amount</th>
<th>Operation</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="log in customizedLogs">
<td ng-bind="log.client_moniker"></td>
<td ng-bind="log.amount|currency:''"></td>
<td>
<a title="Download" ng-href="{{log.aba_file}}" target="_blank"><i class="fa fa-download"></i></a>
</td>
</tr>
</tbody>
</table>
<div ng-if="!customizedLogs.length">
No manual settlements today
</div>
</div>
<div class="modal-footer">
<button class="btn btn-danger" ng-click="$dismiss()">OK</button>
</div>

@ -40,9 +40,13 @@
ng-disabled="noticeResend"> ng-disabled="noticeResend">
Send Settlement Notice Send Settlement Notice
</button> </button>
<button class="btn btn-primary" ng-click="showCustomizedSettle()" ng-if="'customized_settle_list'|withFunc">
<i class="fa fa-money"></i> Manual Settlements
</button>
<button class="btn btn-success pull-right" ng-click="reloadPage()"> <button class="btn btn-success pull-right" ng-click="reloadPage()">
<i class="fa fa-refresh"></i>Reload <i class="fa fa-refresh"></i>Reload
</button> </button>
<a ui-sref="settle_tasks" class="btn btn-primary">Settle Tasks</a> <a ui-sref="settle_tasks" class="btn btn-primary">Settle Tasks</a>
</div> </div>
</div> </div>

@ -0,0 +1,25 @@
package au.com.royalpay.payment.manage.shopify.support;
import org.junit.jupiter.api.Test;
import org.springframework.web.util.UriComponentsBuilder;
import static org.junit.jupiter.api.Assertions.*;
class HmacVerificationUtilTest {
@Test
void checkParameters() {
String message = "host=Z2Vlay10ZXN0LXNob3AubXlzaG9waWZ5LmNvbS9hZG1pbg&shop=geek-test-shop.myshopify.com&timestamp=1648025715";
String key = "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";
String hmac = "803cd4924b19cedc5361ab09776d078a18be3ba32fd7d62de72269a12bec1ffc";
assert HmacVerificationUtil.hmacSHA256(message, key, hmac);
}
@Test
void testQuery() {
String base = "host=Z2Vlay10ZXN0LXNob3AubXlzaG9waWZ5LmNvbS9hZG1pbg&timestamp=1648025715&shop=geek-test-shop.myshopify.com";
String query = UriComponentsBuilder.fromUriString("/shopify/auth?hmac=803cd4924b19cedc5361ab09776d078a18be3ba32fd7d62de72269a12bec1ffc&host=Z2Vlay10ZXN0LXNob3AubXlzaG9waWZ5LmNvbS9hZG1pbg&timestamp=1648025715&shop=geek-test-shop.myshopify.com")
.replaceQueryParam("hmac").build().getQuery();
assertEquals(base, query);
}
}

@ -1,10 +1,8 @@
package au.com.royalpay.payment.manage.valid; package au.com.royalpay.payment.manage.valid;
import au.com.royalpay.payment.tools.env.PlatformEnvironment;
import au.com.royalpay.payment.tools.exceptions.ServerErrorException; import au.com.royalpay.payment.tools.exceptions.ServerErrorException;
import cn.yixblog.platform.http.HttpRequestGenerator; import cn.yixblog.platform.http.HttpRequestGenerator;
import cn.yixblog.platform.http.HttpRequestResult; import cn.yixblog.platform.http.HttpRequestResult;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.junit.Test; import org.junit.Test;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
@ -12,7 +10,6 @@ import org.springframework.web.bind.annotation.RequestMethod;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;

Loading…
Cancel
Save