diff --git a/src/document/openapi/cn/components_order.yml b/src/document/openapi/cn/components_order.yml index 38a9d38f1..ea511b3ea 100644 --- a/src/document/openapi/cn/components_order.yml +++ b/src/document/openapi/cn/components_order.yml @@ -32,6 +32,80 @@ orderBasic: 可以提供以下格式的精确时间:yyyy-MM-dd HH:mm:ss,基于GMT+10时区。 或以以下格式提供:数字+m/h,m=分钟,h=小时 超时时间最小1m,最大24h + extra: + type: object + description: 订单扩展参数,部分渠道必填 + properties: + pay_type: + type: string + description: 钱包类型,AlipayPlus 线上订单必填,默认是alipay_cn + enum: + - alipay_cn + - alipay_hk + - gcash + - dana + - bkash + - kakaopay + - easy_paisa + - tng + - truemoney + flights: + type: array + description: 航班信息,如果有多个航班需分开填入,如果商户业务类型是航班类型且钱包类型为alipay_cn时必填 + items: + type: object + properties: + flight_no: + type: string + description: 航班号 + departure_time: + type: string + format: date-time + example: '202103011203' + pattern: yyyyMMddHHmm + description: 起飞时间(当地时区) + hotels: + type: array + description: 酒店预订信息,如果有多个酒店则分开录入,如果商户类型为旅游且钱包类型为alipay_cn时必填 + items: + type: object + properties: + name: + type: string + description: 酒店名称 + check_in_time: + type: string + format: date + example: '20210301' + pattern: yyyyMMdd + description: 入住日期 + check_out_time: + type: string + format: date + example: '20210302' + pattern: yyyyMMdd + description: 离店日期 + schools: + type: array + description: 留学信息,如果存在多个则分开录入,如果商户类型为留学且钱包类型为alipay_cn时必填 + items: + type: object + properties: + admission_notice_url: + type: string + description: 学校AdmissionNotice网页地址 + goods: + type: array + description: 商品信息,如果存在多个则分开录入,如果商户类型为贸易且钱包类型为alipay_cn时必填 + items: + type: object + properties: + name: + type: string + description: 商品名称 + quantity: + type: number + description: 数量 orderWithChannel: allOf: - $ref: '#/orderBasic' @@ -42,6 +116,7 @@ orderWithChannel: enum: - Alipay - Wechat + - AlipayPlus type: object required: - channel diff --git a/src/document/openapi/cn/document.yml b/src/document/openapi/cn/document.yml index 110937038..d00778a0d 100644 --- a/src/document/openapi/cn/document.yml +++ b/src/document/openapi/cn/document.yml @@ -140,9 +140,9 @@ tags: - name: RetailPay description: | 线下支付订单接口用于线下零售收银,有B扫C和C扫B两种模式 - - name: AlipayOnline + - name: ChannelGateway description: | - 用于PC端支付宝支付,创建订单后跳转到返回的pay_url(需附加签名参数和redirect参数),随后进入支付宝支付页面完成支付 + 用于PC端渠道网关支付,创建订单后跳转到返回的pay_url(需附加签名参数和redirect参数),随后进入渠道收银台页面完成支付 该接口现仅支持支付宝。 - name: CB Bank @@ -212,7 +212,7 @@ paths: - SDK Payment - CB Bank - RetailPay - - AlipayOnline + - ChannelGateway - CardPayment - MiniProgram - MobileH5 @@ -239,7 +239,7 @@ paths: - SDK Payment - CB Bank - RetailPay - - AlipayOnline + - ChannelGateway - CardPayment - MiniProgram - MobileH5 @@ -833,13 +833,13 @@ paths: description: 付款码字符串,商户可自行生成二维码 # todo /alipay/partners/{partner_code}/orders/{partner_order_id}: put: - summary: 支付宝WEB订单下单 + summary: 渠道网关订单下单 x-sort-order: 0 description: | 创建订单后跳转到返回的pay_url(需附加签名参数和redirect参数),随后进入支付宝支付页面完成支付 该接口现仅支持支付宝。 tags: - - AlipayOnline + - ChannelGateway parameters: - name: partner_code in: path @@ -851,7 +851,16 @@ paths: content: application/json: schema: - $ref: 'components_order.yml#/orderBasic' + allOf: + - $ref: 'components_order.yml#/orderBasic' + - type: object + properties: + channel: + type: string + description: 支付渠道,默认为Alipay + enum: + - Alipay + - AlipayPlus responses: 200: description: Order @@ -1016,7 +1025,7 @@ paths: - MobileH5 - MiniProgram - CardPayment - - AlipayOnline + - ChannelGateway - RetailPay - CB Bank - SDK Payment @@ -1062,7 +1071,7 @@ paths: - MobileH5 - MiniProgram - CardPayment - - AlipayOnline + - ChannelGateway - RetailPay - CB Bank - SDK Payment @@ -1234,7 +1243,7 @@ paths: - SDK Payment - CB Bank - RetailPay - - AlipayOnline + - ChannelGateway - CardPayment - MiniProgram - MobileH5 diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/core/MerchantChannelPermissionService.java b/src/main/java/au/com/royalpay/payment/manage/merchants/core/MerchantChannelPermissionService.java new file mode 100644 index 000000000..e4538e039 --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/core/MerchantChannelPermissionService.java @@ -0,0 +1,8 @@ +package au.com.royalpay.payment.manage.merchants.core; + +import au.com.royalpay.payment.channels.rpaypaymentsvc.runtime.request.entities.RPayMerchantEntity; +import com.alibaba.fastjson.JSONObject; + +public interface MerchantChannelPermissionService { + RPayMerchantEntity copyMerchantWarriorConfig(JSONObject manager, String targetClientMoniker, String sourceClientMoniker); +} diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/MerchantChannelPermissionServiceImpl.java b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/MerchantChannelPermissionServiceImpl.java new file mode 100644 index 000000000..e8be89cff --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/MerchantChannelPermissionServiceImpl.java @@ -0,0 +1,81 @@ +package au.com.royalpay.payment.manage.merchants.core.impls; + +import au.com.royalpay.payment.channels.rpaypaymentsvc.mappers.RPayMerchantMapper; +import au.com.royalpay.payment.channels.rpaypaymentsvc.runtime.request.entities.RPayMerchantEntity; +import au.com.royalpay.payment.manage.mappers.system.ClientRateMapper; +import au.com.royalpay.payment.manage.mappers.system.SysClientUpayProfileMapper; +import au.com.royalpay.payment.manage.merchants.core.ClientManager; +import au.com.royalpay.payment.manage.merchants.core.MerchantChannelPermissionService; +import au.com.royalpay.payment.tools.defines.PayChannel; +import au.com.royalpay.payment.tools.exceptions.BadRequestException; +import au.com.royalpay.payment.tools.exceptions.NotFoundException; +import au.com.royalpay.payment.tools.merchants.core.MerchantInfoProvider; +import au.com.royalpay.payment.tools.merchants.exceptions.NoRateConfigException; +import com.alibaba.fastjson.JSONObject; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.Date; + +@Service +public class MerchantChannelPermissionServiceImpl implements MerchantChannelPermissionService { + @Resource + private MerchantInfoProvider merchantInfoProvider; + @Resource + private ClientManager clientManager; + @Resource + private SysClientUpayProfileMapper sysClientUpayProfileMapper; + @Resource + private RPayMerchantMapper rPayMerchantMapper; + @Resource + private ClientRateMapper clientRateMapper; + + @Override + @Transactional + public RPayMerchantEntity copyMerchantWarriorConfig(JSONObject manager, String targetClientMoniker, String sourceClientMoniker) { + JSONObject targetMerchant = merchantInfoProvider.getClientInfoByMoniker(targetClientMoniker); + if (targetMerchant == null) { + throw new NotFoundException("Merchant not found:" + targetClientMoniker); + } + JSONObject sourceMerchant = merchantInfoProvider.getClientInfoByMoniker(sourceClientMoniker); + if (sourceMerchant == null) { + throw new NotFoundException("Merchant not found:" + sourceClientMoniker); + } + int sourceClientId = sourceMerchant.getIntValue("client_id"); + int targetClientId = targetMerchant.getIntValue("client_id"); + JSONObject targetProfile = sysClientUpayProfileMapper.findInfo(targetClientId); + if (targetProfile == null) { + JSONObject sourceProfile = sysClientUpayProfileMapper.findInfo(sourceClientId); + if (sourceProfile == null) { + throw new BadRequestException("Missing merchant's UPay profile"); + } + targetProfile = new JSONObject(sourceProfile); + targetProfile.put("client_id", targetClientId); + targetProfile.put("client_moniker", targetMerchant.getString("client_moniker")); + sysClientUpayProfileMapper.save(targetProfile); + } + RPayMerchantEntity targetRPayMch = rPayMerchantMapper.findMerchant(targetClientId); + if (targetRPayMch == null) { + RPayMerchantEntity sourceRPayMch = rPayMerchantMapper.findMerchant(sourceClientId); + if (sourceRPayMch == null) { + throw new BadRequestException("Source merchant not enabled card payment"); + } + targetRPayMch = sourceRPayMch; + targetRPayMch.setClientId(targetMerchant.getIntValue("client_id")); + targetRPayMch.setClientMoniker(targetMerchant.getString("client_moniker")); + rPayMerchantMapper.save(targetRPayMch); + } + clientManager.switchPermission(manager, targetClientMoniker, "enable_rpaypmt_card", sourceMerchant.getBooleanValue("enable_rpaypmt_card")); + clientManager.switchPermission(manager, targetClientMoniker, "enable_rpaypmt_dd", sourceMerchant.getBooleanValue("enable_rpaypmt_dd")); + try { + merchantInfoProvider.clientCurrentRate(targetClientId, new Date(), PayChannel.RPAY_CHANNEL_CARD.getChannelCode()); + } catch (NoRateConfigException e) { + JSONObject rate = merchantInfoProvider.clientCurrentRate(sourceClientId, new Date(), PayChannel.RPAY_CHANNEL_CARD.getChannelCode()); + rate.put("client_id", targetClientId); + rate.remove("client_rate_id"); + clientRateMapper.saveRate(rate); + } + return targetRPayMch; + } +} diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerManageController.java b/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerManageController.java index 628043377..efd63bec4 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerManageController.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/web/PartnerManageController.java @@ -5,6 +5,7 @@ import au.com.royalpay.payment.core.exceptions.InvalidShortIdException; import au.com.royalpay.payment.manage.dev.core.MerchantLocationService; import au.com.royalpay.payment.manage.merchants.beans.*; import au.com.royalpay.payment.manage.merchants.core.ClientManager; +import au.com.royalpay.payment.manage.merchants.core.MerchantChannelPermissionService; import au.com.royalpay.payment.manage.merchants.core.bank.AustraliaBankClientNullException; import au.com.royalpay.payment.manage.permission.manager.ManagerMapping; import au.com.royalpay.payment.manage.permission.manager.RequireManager; @@ -41,6 +42,8 @@ public class PartnerManageController { @Resource private TradeLogService tradeLogService; @Resource + private MerchantChannelPermissionService merchantChannelPermissionService; + @Resource private MerchantLocationService merchantLocationService; @RequestMapping(method = RequestMethod.GET) @@ -441,7 +444,7 @@ public class PartnerManageController { @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { try { return clientManager.getBankInfo(manager, clientMoniker, bsbNo); - }catch (AustraliaBankClientNullException e){ + } catch (AustraliaBankClientNullException e) { throw new InvalidShortIdException(); } } @@ -850,13 +853,13 @@ public class PartnerManageController { @ManagerMapping(value = "/{clientMoniker}/get_merchant_ids/{merchantAppId}", method = RequestMethod.PUT, role = {ManagerRole.OPERATOR, ManagerRole.ADMIN}) public void changeSubMerchantApplication(@PathVariable("clientMoniker") String clientMoniker, @PathVariable("merchantAppId") String merchantAppId, - @RequestBody NewSubMerchantIdApply subMerchantIdApply, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { - clientManager.changeApplicationSubMerchantById(clientMoniker, merchantAppId,subMerchantIdApply,manager); + @RequestBody NewSubMerchantIdApply subMerchantIdApply, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { + clientManager.changeApplicationSubMerchantById(clientMoniker, merchantAppId, subMerchantIdApply, manager); } @ManagerMapping(value = "/{clientMoniker}/get_merchant_ids/{subMerchantId}/status", method = RequestMethod.GET, role = {ManagerRole.OPERATOR, ManagerRole.ADMIN}) - public JSONObject querySubMerchantStatus(@PathVariable("clientMoniker") String clientMoniker,@PathVariable("subMerchantId") String subMerchantId){ - return clientManager.querySubMerchantStatus(clientMoniker,subMerchantId); + public JSONObject querySubMerchantStatus(@PathVariable("clientMoniker") String clientMoniker, @PathVariable("subMerchantId") String subMerchantId) { + return clientManager.querySubMerchantStatus(clientMoniker, subMerchantId); } @ManagerMapping(value = "/{clientMoniker}/register/alipay_gms", method = RequestMethod.POST, role = {ManagerRole.OPERATOR, ManagerRole.ADMIN}) @@ -1031,6 +1034,12 @@ public class PartnerManageController { return clientManager.queryMWMerchantIdStatus(clientMoniker, manager); } + @ManagerMapping(value = "/{clientMoniker}/copy_mw_config", method = RequestMethod.POST, role = {ManagerRole.DEVELOPER}) + public RPayMerchantEntity copyMWConfig(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, + @RequestBody JSONObject body) { + return merchantChannelPermissionService.copyMerchantWarriorConfig(manager, clientMoniker, body.getString("client_moniker")); + } + @ManagerMapping(value = "/{clientMoniker}/query/mw_info", method = RequestMethod.GET, role = {ManagerRole.OPERATOR, ManagerRole.ADMIN}) public RPayMerchantEntity queryMWMerchantInfo(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { return clientManager.queryMWMerchantInfo(clientMoniker, manager); diff --git a/src/main/resources/application-proxy.yml b/src/main/resources/application-proxy.yml index ea2691494..ea9b304c2 100644 --- a/src/main/resources/application-proxy.yml +++ b/src/main/resources/application-proxy.yml @@ -5,8 +5,8 @@ spring: master: driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://${spring.datasource.host}/${spring.datasource.schema-name}?useUnicode=true&characterEncoding=utf8&useSSL=false - password: read0nly - username: readonly + password: ZOIBhellor0yalpay + username: root schema-name: royalpay_production slave: driver-class-name: com.mysql.cj.jdbc.Driver diff --git a/src/main/ui/static/commons/services/commonDialog.js b/src/main/ui/static/commons/services/commonDialog.js index a089a7bf2..42d70ab64 100644 --- a/src/main/ui/static/commons/services/commonDialog.js +++ b/src/main/ui/static/commons/services/commonDialog.js @@ -106,7 +106,7 @@ define(['../app', 'angular'], function (app, angular) { } }, controller:['$scope','cfg',function ($scope, cfg) { - $scope.title = cfg.title || 'Input Amount'; + $scope.title = cfg.title || 'Input Text'; $scope.data = {}; $scope.submit = function () { $scope.$close($scope.data.text); diff --git a/src/main/ui/static/payment/partner/partner-manage.js b/src/main/ui/static/payment/partner/partner-manage.js index a934153a5..2fda3e242 100644 --- a/src/main/ui/static/payment/partner/partner-manage.js +++ b/src/main/ui/static/payment/partner/partner-manage.js @@ -5685,6 +5685,21 @@ define(['angular', 'decimal', 'static/commons/commons', 'uiBootstrap', 'uiRouter }); }; + $scope.copyMWProfile = function () { + commonDialog.inputText({title:'请输入复制来源商户编码'}).then(function (text) { + $http.put('/sys/partners/' + $scope.partner.client_moniker + '/copy_mw_config',{client_moniker: text}).then(function (resp) { + commonDialog.alert({ + title: 'Success', + content: 'Modify successfully', + type: 'success' + }); + $scope.loadPartnerInfo(); + },function (resp) { + commonDialog.alert({ title: 'Error', content: resp.data.message, type: 'error' }); + }) + }); + }; + // $scope.showMoreMerchantInfo = false; // $scope.hideMerchantInfo = function () { // $scope.showMoreMerchantInfo = !$scope.showMoreMerchantInfo; diff --git a/src/main/ui/static/payment/partner/templates/sub_merchant_id_apply.html b/src/main/ui/static/payment/partner/templates/sub_merchant_id_apply.html index f4d7af204..439260e97 100644 --- a/src/main/ui/static/payment/partner/templates/sub_merchant_id_apply.html +++ b/src/main/ui/static/payment/partner/templates/sub_merchant_id_apply.html @@ -281,6 +281,11 @@ Apply +
{{order.name}}
{{order.card_bank}}
{{order.card_type}}
{{order.card_alias}}
diff --git a/src/test/java/au/com/royalpay/payment/manage/merchants/core/impls/MerchantChannelPermissionServiceImplTest.java b/src/test/java/au/com/royalpay/payment/manage/merchants/core/impls/MerchantChannelPermissionServiceImplTest.java new file mode 100644 index 000000000..e40799fcd --- /dev/null +++ b/src/test/java/au/com/royalpay/payment/manage/merchants/core/impls/MerchantChannelPermissionServiceImplTest.java @@ -0,0 +1,30 @@ +package au.com.royalpay.payment.manage.merchants.core.impls; + +import au.com.royalpay.payment.manage.mappers.system.ManagerMapper; +import au.com.royalpay.payment.manage.merchants.core.MerchantChannelPermissionService; +import com.alibaba.fastjson.JSONObject; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ActiveProfiles; +import org.springframework.test.context.junit4.SpringRunner; + +import javax.annotation.Resource; + +@RunWith(SpringRunner.class) +@SpringBootTest +@ActiveProfiles({"proxy","common", "alipay", "wechat", "rpay", "rppaysvc"}) +public class MerchantChannelPermissionServiceImplTest { + + @Resource + private MerchantChannelPermissionService merchantChannelPermissionService; + + @Resource + private ManagerMapper managerMapper; + + @Test + public void test() { + JSONObject manager = managerMapper.findByLoginId("yixian"); + merchantChannelPermissionService.copyMerchantWarriorConfig(manager, "DV11", "DV02"); + } +} \ No newline at end of file