diff --git a/pom.xml b/pom.xml index 813476a9e..cd716e686 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ 4.0.0 manage - 1.1.11 + 1.1.12 UTF-8 @@ -33,11 +33,11 @@ au.com.royalpay.payment - hf-core + alipay-core au.com.royalpay.payment - alipay-core + hf-core au.com.royalpay.payment @@ -55,15 +55,15 @@ au.com.royalpay.payment lakala-core + + au.com.royalpay.payment + bestpay-core + com.github.stuxuhai jpinyin 1.1.7 - - au.com.royalpay.payment - bestpay-core - org.springframework.boot spring-boot-starter @@ -207,7 +207,7 @@ com.zaxxer HikariCP - 3.3.1 + 3.2.0 @@ -276,10 +276,10 @@ ${jib-maven-plugin.version} - hkccr.ccs.tencentyun.com/rpay/serverjre:openj9 + hkccr.ccs.tencentyun.com/cross-payment/base:v1.0 - hkccr.ccs.tencentyun.com/rpay/manage:${docker-image.version} + hkccr.ccs.tencentyun.com/cb-payment/manage:${docker-image.version} extra/ diff --git a/src/main/java/au/com/royalpay/payment/manage/application/core/SimpleClientApplyService.java b/src/main/java/au/com/royalpay/payment/manage/application/core/SimpleClientApplyService.java index d3a877528..31227f532 100644 --- a/src/main/java/au/com/royalpay/payment/manage/application/core/SimpleClientApplyService.java +++ b/src/main/java/au/com/royalpay/payment/manage/application/core/SimpleClientApplyService.java @@ -31,4 +31,7 @@ public interface SimpleClientApplyService { JSONObject getBankInfo(String bsb_no); void checkAccountName(String contact_phone,String nation_code); + + void subscribeNewsletter(String mail, String lang); + } diff --git a/src/main/java/au/com/royalpay/payment/manage/application/core/impls/SimpleClientApplyServiceImpl.java b/src/main/java/au/com/royalpay/payment/manage/application/core/impls/SimpleClientApplyServiceImpl.java index 2abaa88ee..30987a49d 100644 --- a/src/main/java/au/com/royalpay/payment/manage/application/core/impls/SimpleClientApplyServiceImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/application/core/impls/SimpleClientApplyServiceImpl.java @@ -16,7 +16,6 @@ import au.com.royalpay.payment.manage.signin.core.SignInAccountService; import au.com.royalpay.payment.manage.support.sms.SmsSender; import au.com.royalpay.payment.manage.system.core.MailGunService; import au.com.royalpay.payment.tools.env.PlatformEnvironment; -import au.com.royalpay.payment.tools.env.RequestEnvironment; import au.com.royalpay.payment.tools.env.SysConfigManager; import au.com.royalpay.payment.tools.exceptions.BadRequestException; import au.com.royalpay.payment.tools.exceptions.ForbiddenException; @@ -26,14 +25,12 @@ import au.com.royalpay.payment.tools.locale.LocaleSupport; import au.com.royalpay.payment.tools.utils.PasswordUtils; import com.alibaba.fastjson.JSONObject; -import com.github.qcloudsms.SmsSingleSender; import org.apache.catalina.servlet4preview.http.HttpServletRequest; import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.time.DateFormatUtils; import org.apache.commons.lang3.time.DateUtils; -import org.springframework.beans.factory.annotation.Value; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -91,6 +88,8 @@ public class SimpleClientApplyServiceImpl implements SimpleClientApplyService { private PmtSubMerchantIdMapper pmtSubMerchantIdMapper; @Resource private ManagerMapper managerMapper; + @Resource + private SysCustomerSubscribeMapper subscribeMapper; @Resource private ClientBDMapper clientBDMapper; @@ -247,6 +246,41 @@ public class SimpleClientApplyServiceImpl implements SimpleClientApplyService { } } + @Override + public void subscribeNewsletter(String mail, String lang) { + JSONObject subscribeInfo = subscribeMapper.findByEmail(mail); + Date newDate = new Date(); + if (subscribeInfo != null && subscribeInfo.getBoolean("is_valid")) { + throw new BadRequestException("您已订阅成功,请勿重新提交"); + } + String imageUrl = lang == null || "zh".equals(lang) ? "royalpay_newsletter_thank_you.png" : "royalpay_newsletter_thank_you_en.png"; + Context ctx = new Context(); + ctx.setVariable("imageUrl", PlatformEnvironment.getEnv().concatUrl("/static/images/" + imageUrl)); + final String content = thymeleaf.process("mail/subscribe_mail.html", ctx); + try { + String emailId = mailService.sendEmail("You have successfully subscribed to Newsletter", mail, "", content); + if (subscribeInfo == null) { + subscribeInfo = new JSONObject(); + subscribeInfo.put("approve_email_id", emailId); + subscribeInfo.put("subscribe_email", mail); + subscribeInfo.put("create_time", newDate); + subscribeInfo.put("update_time", newDate); + subscribeMapper.save(subscribeInfo); + return; + } + if (!subscribeInfo.getBoolean("is_valid")) { + subscribeInfo.put("approve_email_id", emailId); + subscribeInfo.put("is_valid", 1); + subscribeInfo.put("update_time", newDate); + subscribeMapper.update(subscribeInfo); + } + + + } catch (URISyntaxException | IOException e) { + e.printStackTrace(); + } + } + @Override @Transactional public void saveOrUpdateApplyInfo(JSONObject applyInfo, String username) { diff --git a/src/main/java/au/com/royalpay/payment/manage/application/web/SimpleClientApplyController.java b/src/main/java/au/com/royalpay/payment/manage/application/web/SimpleClientApplyController.java index 354ee5d21..0efaf7f5f 100644 --- a/src/main/java/au/com/royalpay/payment/manage/application/web/SimpleClientApplyController.java +++ b/src/main/java/au/com/royalpay/payment/manage/application/web/SimpleClientApplyController.java @@ -3,6 +3,7 @@ package au.com.royalpay.payment.manage.application.web; import au.com.royalpay.payment.manage.application.beans.ClientPreApplyBean; import au.com.royalpay.payment.manage.application.beans.ClientPreApplyStep1Bean; import au.com.royalpay.payment.manage.application.core.SimpleClientApplyService; +import au.com.royalpay.payment.manage.notice.core.MailService; import au.com.royalpay.payment.tools.env.SysConfigManager; import com.alibaba.fastjson.JSONObject; @@ -17,9 +18,13 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.ModelAndView; +import org.thymeleaf.context.Context; +import org.thymeleaf.spring4.SpringTemplateEngine; import javax.annotation.Resource; import javax.validation.Valid; +import java.io.IOException; +import java.net.URISyntaxException; @RestController @RequestMapping("/register") @@ -90,5 +95,10 @@ public class SimpleClientApplyController { return JSONObject.parseObject(sysConfig.getString("sys_apply_rates")); } + @RequestMapping(value = "/send/mail/subscribe", method = RequestMethod.GET) + public void sendSubscribeMail(@RequestParam(value = "mail", required = true) String mail, @RequestParam("lang") String lang) { + simpleClientApplyService.subscribeNewsletter(mail, lang); + } + } diff --git a/src/main/java/au/com/royalpay/payment/manage/customers/beans/CustomerComment.java b/src/main/java/au/com/royalpay/payment/manage/customers/beans/CustomerComment.java new file mode 100644 index 000000000..3778a68c1 --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/customers/beans/CustomerComment.java @@ -0,0 +1,81 @@ +package au.com.royalpay.payment.manage.customers.beans; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.annotation.JSONField; +import org.hibernate.validator.constraints.NotEmpty; + +import java.util.Date; + +public class CustomerComment { + + @NotEmpty(message = "error.payment.valid.param_missing") + @JSONField(name = "first_name") + private String firstName; + + @NotEmpty(message = "error.payment.valid.param_missing") + @JSONField(name = "last_name") + private String lastName; + + @NotEmpty(message = "error.payment.valid.param_missing") + private String email; + + private String comment; + + @JSONField(name = "create_time") + private Date createTime; + + private int status; + + public JSONObject insertObject() { + return (JSONObject) JSON.toJSON(this); + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getComment() { + return comment; + } + + public void setComment(String comment) { + this.comment = comment; + } + + public Date getCreateTime() { + return createTime; + } + + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } +} diff --git a/src/main/java/au/com/royalpay/payment/manage/customers/core/CustomerCommentService.java b/src/main/java/au/com/royalpay/payment/manage/customers/core/CustomerCommentService.java new file mode 100644 index 000000000..0de3f5971 --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/customers/core/CustomerCommentService.java @@ -0,0 +1,8 @@ +package au.com.royalpay.payment.manage.customers.core; + +import au.com.royalpay.payment.manage.customers.beans.CustomerComment; + +public interface CustomerCommentService { + + void save(CustomerComment customerComment); +} diff --git a/src/main/java/au/com/royalpay/payment/manage/customers/core/impls/CustomerCommentServiceImpl.java b/src/main/java/au/com/royalpay/payment/manage/customers/core/impls/CustomerCommentServiceImpl.java new file mode 100644 index 000000000..1a0ead10f --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/customers/core/impls/CustomerCommentServiceImpl.java @@ -0,0 +1,22 @@ +package au.com.royalpay.payment.manage.customers.core.impls; + +import au.com.royalpay.payment.manage.customers.beans.CustomerComment; +import au.com.royalpay.payment.manage.customers.core.CustomerCommentService; +import au.com.royalpay.payment.manage.mappers.system.SysCustomerCommentMapper; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Date; + +@Service +public class CustomerCommentServiceImpl implements CustomerCommentService { + + @Resource + private SysCustomerCommentMapper customerCommentMapper; + + @Override + public void save(CustomerComment customerComment) { + customerComment.setCreateTime(new Date()); + customerCommentMapper.save(customerComment.insertObject()); + } +} diff --git a/src/main/java/au/com/royalpay/payment/manage/customers/web/CustomerCommentController.java b/src/main/java/au/com/royalpay/payment/manage/customers/web/CustomerCommentController.java new file mode 100644 index 000000000..da2d84f6f --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/customers/web/CustomerCommentController.java @@ -0,0 +1,26 @@ +package au.com.royalpay.payment.manage.customers.web; + +import au.com.royalpay.payment.manage.customers.beans.CustomerComment; +import au.com.royalpay.payment.manage.customers.core.CustomerCommentService; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.validation.Valid; + +/** + * 客户联系 + */ +@RequestMapping("/customer") +@RestController +public class CustomerCommentController { + + @Resource + private CustomerCommentService customerCommentService; + + @RequestMapping("/contact/comment") + public void saveCustomerComment(@RequestBody @Valid CustomerComment customerComment) { + customerCommentService.save(customerComment); + } +} diff --git a/src/main/java/au/com/royalpay/payment/manage/mappers/system/SysCustomerCommentMapper.java b/src/main/java/au/com/royalpay/payment/manage/mappers/system/SysCustomerCommentMapper.java new file mode 100644 index 000000000..99e2a3f63 --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/mappers/system/SysCustomerCommentMapper.java @@ -0,0 +1,13 @@ +package au.com.royalpay.payment.manage.mappers.system; + +import cn.yixblog.support.mybatis.autosql.annotations.AutoMapper; +import cn.yixblog.support.mybatis.autosql.annotations.AutoSql; +import cn.yixblog.support.mybatis.autosql.annotations.SqlType; +import com.alibaba.fastjson.JSONObject; + +@AutoMapper(tablename = "sys_customer_comment", pkName = "id") +public interface SysCustomerCommentMapper { + + @AutoSql(type = SqlType.INSERT) + void save(JSONObject info); +} diff --git a/src/main/java/au/com/royalpay/payment/manage/mappers/system/SysCustomerSubscribeMapper.java b/src/main/java/au/com/royalpay/payment/manage/mappers/system/SysCustomerSubscribeMapper.java new file mode 100644 index 000000000..a892dcb81 --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/mappers/system/SysCustomerSubscribeMapper.java @@ -0,0 +1,20 @@ +package au.com.royalpay.payment.manage.mappers.system; + +import cn.yixblog.support.mybatis.autosql.annotations.AutoMapper; +import cn.yixblog.support.mybatis.autosql.annotations.AutoSql; +import cn.yixblog.support.mybatis.autosql.annotations.SqlType; +import com.alibaba.fastjson.JSONObject; +import org.apache.ibatis.annotations.Param; + +@AutoMapper(tablename = "sys_customer_subscribe", pkName = "id") +public interface SysCustomerSubscribeMapper { + + @AutoSql(type = SqlType.INSERT) + void save(JSONObject info); + + @AutoSql(type = SqlType.SELECT) + JSONObject findByEmail(@Param("subscribe_email") String email); + + @AutoSql(type = SqlType.UPDATE) + void update(JSONObject subscribeInfo); +} diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/beans/ClientApplyInfo.java b/src/main/java/au/com/royalpay/payment/manage/merchants/beans/ClientApplyInfo.java index 5095295ae..e7d6a54d2 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/beans/ClientApplyInfo.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/beans/ClientApplyInfo.java @@ -45,6 +45,8 @@ public class ClientApplyInfo { private String industry; private int source = 0; private String remark; + @JSONField(name = "aus_mch_category") + private String ausMchCategory; public JSONObject insertObject() { @@ -251,6 +253,14 @@ public class ClientApplyInfo { this.industry = industry; } + public String getAusMchCategory() { + return ausMchCategory; + } + + public void setAusMchCategory(String ausMchCategory) { + this.ausMchCategory = ausMchCategory; + } + @Override public String toString() { return "ClientApplyInfo{" + diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/core/ClientManager.java b/src/main/java/au/com/royalpay/payment/manage/merchants/core/ClientManager.java index 80fd0479f..1046aebca 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/core/ClientManager.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/core/ClientManager.java @@ -39,6 +39,8 @@ public interface ClientManager { JSONObject listClients(JSONObject manager, PartnerQuery query); + void exportClients(JSONObject manager,PartnerQuery query,HttpServletResponse resp); + JSONObject listClientsByApp(JSONObject manager, AppMerchantBean query); List listPartners(JSONObject manager, PartnerQuery query); diff --git a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java index 874a73ff8..88d98677a 100644 --- a/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java +++ b/src/main/java/au/com/royalpay/payment/manage/merchants/core/impls/ClientManagerImpl.java @@ -40,6 +40,7 @@ import au.com.royalpay.payment.manage.permission.utils.OrgCheckUtils; import au.com.royalpay.payment.manage.signin.beans.TodoNotice; import au.com.royalpay.payment.manage.signin.core.ManagerTodoNoticeProvider; import au.com.royalpay.payment.manage.signin.core.SignInAccountService; +import au.com.royalpay.payment.manage.support.serverless.ServerlessFunctionTrigger; import au.com.royalpay.payment.manage.support.sms.SmsSender; import au.com.royalpay.payment.manage.system.core.ClientContractService; import au.com.royalpay.payment.manage.system.core.MailGunService; @@ -281,6 +282,8 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid @Resource private CommonSubMerchantIdMapper commonSubMerchantIdMapper; @Resource + private ServerlessFunctionTrigger serverlessFunctionTrigger; + @Resource private Locker locker; @Resource private MongoTemplate mongoTemplate; @@ -346,27 +349,27 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } String same_phone = clientMapper.findSamePhone(client.getString("contact_phone")).getString("a"); - if(same_phone!=null&& client.getString("contact_phone")!= null&&same_phone.contains(" ") ) { - same_phone = same_phone.replace(client.getString("client_moniker"),""); - client.put("same_phone","(雷同商户:"+same_phone+")" ); + if (same_phone != null && client.getString("contact_phone") != null && same_phone.contains(" ")) { + same_phone = same_phone.replace(client.getString("client_moniker"), ""); + client.put("same_phone", "(雷同商户:" + same_phone + ")"); } String same_company_name = clientMapper.findSameCompanyName(client.getString("company_name")).getString("a"); - if(same_company_name!=null&& client.getString("company_name")!= null&&same_company_name.contains(" ") ) { - same_company_name = same_company_name.replace(client.getString("client_moniker"),""); - client.put("same_company_name","(雷同商户:"+same_company_name+")" ); + if (same_company_name != null && client.getString("company_name") != null && same_company_name.contains(" ")) { + same_company_name = same_company_name.replace(client.getString("client_moniker"), ""); + client.put("same_company_name", "(雷同商户:" + same_company_name + ")"); } String same_email = clientMapper.findSameEmail(client.getString("contact_email")).getString("a"); - if(same_email!=null&& client.getString("contact_email")!= null&&same_email.contains(" ") ) { - same_email = same_email.replace(client.getString("client_moniker"),""); - client.put("same_email","(雷同商户:"+same_email+")" ); + if (same_email != null && client.getString("contact_email") != null && same_email.contains(" ")) { + same_email = same_email.replace(client.getString("client_moniker"), ""); + client.put("same_email", "(雷同商户:" + same_email + ")"); } String same_address = clientMapper.findSameAddress(client.getString("address")).getString("a"); - if(same_address!=null&& client.getString("address")!= null&&same_address.contains(" ") ) { - same_address = same_address.replace(client.getString("client_moniker"),""); - client.put("same_address","(雷同商户:"+same_address+")" ); + if (same_address != null && client.getString("address") != null && same_address.contains(" ")) { + same_address = same_address.replace(client.getString("client_moniker"), ""); + client.put("same_address", "(雷同商户:" + same_address + ")"); } @@ -445,8 +448,8 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } //商户支付场景 if (StringUtils.isNotBlank(client.getString("client_pay_type"))) { - client.put("client_pay_type",client.getString("client_pay_type").split(",")); - client.put("client_pay_desc",client.getString("client_pay_desc").split(",")); + client.put("client_pay_type", client.getString("client_pay_type").split(",")); + client.put("client_pay_desc", client.getString("client_pay_desc").split(",")); } if (StringUtils.isNotBlank(client.getString("parent_client_id")) && sysClientMapper.childClientId(client.getIntValue("client_id")).size() > 0) { @@ -487,6 +490,39 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid @Override public JSONObject listClients(JSONObject manager, PartnerQuery query) { + JSONObject params = prepareListClientsParameter(manager, query); + PageList partners = clientMapper.listPartners(params, + new PageBounds(query.getPage(), query.getLimit(), Order.formString("is_valid.desc,-approve_time.asc,create_time.desc"))); + int authDays = PlatformEnvironment.getEnv().authDays();// 快速自助开通申请有效期 + for (JSONObject partner : partners) { + String subMerchantId = partner.getString("sub_merchant_id"); + if (subMerchantId != null) { + partner.put("temp_sub_merchant", checkSubMerchantIdInCommonPool(subMerchantId)); + } + if (partner.getIntValue("approve_result") == 2) { + partner.put("expiry_time", DateUtils.addDays(partner.getDate("approve_time"), authDays)); + partner.put("pass_timeout", DateUtils.addDays(partner.getDate("approve_time"), authDays).compareTo(new Date()) < 0); + } + } + return PageListUtils.buildPageListResult(partners); + } + + @Override + public void exportClients(JSONObject manager, PartnerQuery query, HttpServletResponse resp) { + JSONObject params = prepareListClientsParameter(manager, query); + JSONObject retResp = serverlessFunctionTrigger.triggerFunction("export_merchants", params); + String contentB64 = retResp.getString("content"); + resp.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + resp.setHeader("Content-Disposition", "attachment; filename=merchants.xlsx"); + try (OutputStream out = resp.getOutputStream()) { + IOUtils.write(Base64.decodeBase64(contentB64), out); + out.flush(); + } catch (IOException e) { + throw new ServerErrorException(e); + } + } + + private JSONObject prepareListClientsParameter(JSONObject manager, PartnerQuery query) { JSONObject params = query.toJsonParam(); if (params.getString("org_id") != null) { if (params.getString("org_ids") == null) { @@ -549,20 +585,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid params.put("temp_mch_id", tempSubMchId); params.put("temp_mch_id_source", tempSubMchSource); } - PageList partners = clientMapper.listPartners(params, - new PageBounds(query.getPage(), query.getLimit(), Order.formString("is_valid.desc,-approve_time.asc,create_time.desc"))); - int authDays = PlatformEnvironment.getEnv().authDays();// 快速自助开通申请有效期 - for (JSONObject partner : partners) { - String subMerchantId = partner.getString("sub_merchant_id"); - if (subMerchantId != null) { - partner.put("temp_sub_merchant", checkSubMerchantIdInCommonPool(subMerchantId)); - } - if (partner.getIntValue("approve_result") == 2) { - partner.put("expiry_time", DateUtils.addDays(partner.getDate("approve_time"), authDays)); - partner.put("pass_timeout", DateUtils.addDays(partner.getDate("approve_time"), authDays).compareTo(new Date()) < 0); - } - } - return PageListUtils.buildPageListResult(partners); + return params; } @Override @@ -797,7 +820,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid JSONObject clientConfig = new JSONObject(); clientConfig.put("client_id", clientId); clientConfig.put("client_moniker", client.getString("client_moniker")); - if (StringUtils.isNotBlank(updateInfo.getString("client_pay_type"))&& StringUtils.isNotBlank(updateInfo.getString("client_pay_desc"))) { + if (StringUtils.isNotBlank(updateInfo.getString("client_pay_type")) && StringUtils.isNotBlank(updateInfo.getString("client_pay_desc"))) { clientConfig.put("client_pay_type", updateInfo.getString("client_pay_type")); clientConfig.put("client_pay_desc", updateInfo.getString("client_pay_desc")); } @@ -3481,7 +3504,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid throw new ForbiddenException("Cashier has no permission to switch retail surcharge"); } clientModifySupport - .processClientConfigModify(new SwitchPermissionModify(account, client.getString("client_moniker"), "cbbank_surcharge", paySurcharge),true); + .processClientConfigModify(new SwitchPermissionModify(account, client.getString("client_moniker"), "cbbank_surcharge", paySurcharge), true); } @Override @@ -5167,6 +5190,7 @@ public class ClientManagerImpl implements ClientManager, ManagerTodoNoticeProvid } }); } + private TemplateMessage initSendTestPasswordTemplate(String wxopenid, String templateId) { TemplateMessage msg = new TemplateMessage(wxopenid, templateId, PlatformEnvironment.getEnv().concatUrl("testMerchantPassword")); msg.put("first", "系统测试商户账户已重置", "#000000"); 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 b32ff4b9b..31103b707 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 @@ -43,6 +43,11 @@ public class PartnerManageController { return clientManager.listClients(manager, query); } + @ManagerMapping(value = "/exporting_excel", method = RequestMethod.GET, role = {ManagerRole.ADMIN, ManagerRole.OPERATOR, ManagerRole.FINANCIAL_STAFF}) + public void exportClientsExcel(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, PartnerQuery query, HttpServletResponse resp) { + clientManager.exportClients(manager, query, resp); + } + @RequestMapping(value = "/list", method = RequestMethod.GET) @RequireManager(role = {ManagerRole.ADMIN, ManagerRole.BD_USER, ManagerRole.OPERATOR, ManagerRole.SERVANT, ManagerRole.DIRECTOR}) public List lisPartners(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, PartnerQuery query) { @@ -94,7 +99,7 @@ public class PartnerManageController { response.setContentType("application/octet-stream;"); response.addHeader("Content-Disposition", "attachment; filename=qr_board.jpg"); OutputStream ous = response.getOutputStream(); - clientManager.writeQrCodeBoard(manager, clientMoniker, config, ous,"PC"); + clientManager.writeQrCodeBoard(manager, clientMoniker, config, ous, "PC"); } @ManagerMapping(value = "/{clientMoniker}/qrcode_board/aggregate", method = RequestMethod.GET) @@ -103,16 +108,16 @@ public class PartnerManageController { response.setContentType("application/octet-stream;"); response.addHeader("Content-Disposition", "attachment; filename=qr_board.jpg"); OutputStream ous = response.getOutputStream(); - clientManager.writeAggregateQrCodeBoard(manager, clientMoniker, config, ous,"PC"); + clientManager.writeAggregateQrCodeBoard(manager, clientMoniker, config, ous, "PC"); } @ManagerMapping(value = "/{clientMoniker}/qrcode_board/CBBankAggregate", method = RequestMethod.GET) public void getCBBankAggregateQRCodeBoardImage(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, - HttpServletResponse response) throws IOException { + HttpServletResponse response) throws IOException { response.setContentType("application/octet-stream;"); response.addHeader("Content-Disposition", "attachment; filename=qr_board.jpg"); OutputStream ous = response.getOutputStream(); - clientManager.writeCBBankAggregateQrCodeBoard(manager, clientMoniker, ous,"PC"); + clientManager.writeCBBankAggregateQrCodeBoard(manager, clientMoniker, ous, "PC"); } @ManagerMapping(value = "/{clientMoniker}/poster", method = RequestMethod.GET) @@ -141,18 +146,18 @@ public class PartnerManageController { } @ManagerMapping(value = "/{clientMoniker}/max_order_amount", method = RequestMethod.PUT, role = {ManagerRole.OPERATOR}) - public void setMaxOrderAmount(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager,@PathVariable String clientMoniker, @RequestBody JSONObject limit) { - clientManager.setMaxOrderAmount(manager,clientMoniker, limit.getBigDecimal("limit")); + public void setMaxOrderAmount(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, @PathVariable String clientMoniker, @RequestBody JSONObject limit) { + clientManager.setMaxOrderAmount(manager, clientMoniker, limit.getBigDecimal("limit")); } @ManagerMapping(value = "/{clientMoniker}/customer_surcharge_rate", method = RequestMethod.PUT, role = {ManagerRole.ADMIN}) - public void setCustomerSurchargeRate(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager,@PathVariable String clientMoniker, @RequestBody JSONObject config) { - clientManager.setCustomerSurchargeRate(manager,clientMoniker, config.getBigDecimal("customer_surcharge_rate")); + public void setCustomerSurchargeRate(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, @PathVariable String clientMoniker, @RequestBody JSONObject config) { + clientManager.setCustomerSurchargeRate(manager, clientMoniker, config.getBigDecimal("customer_surcharge_rate")); } @ManagerMapping(value = "/{clientMoniker}/order_expiry_config", method = RequestMethod.PUT, role = {ManagerRole.ADMIN}) - public void setOrderExpiryConfig(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager,@PathVariable String clientMoniker, @RequestBody JSONObject config) { - clientManager.setOrderExpiryConfig(manager,clientMoniker, config.getString("order_expiry_config")); + public void setOrderExpiryConfig(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, @PathVariable String clientMoniker, @RequestBody JSONObject config) { + clientManager.setOrderExpiryConfig(manager, clientMoniker, config.getString("order_expiry_config")); } @ManagerMapping(value = "/{clientMoniker}", method = RequestMethod.PUT, role = {ManagerRole.ADMIN, ManagerRole.BD_USER, ManagerRole.OPERATOR}) @@ -207,43 +212,43 @@ public class PartnerManageController { } @ManagerMapping(value = "/{clientMoniker}/qrcode_surcharge", method = RequestMethod.PUT, role = {ManagerRole.OPERATOR, ManagerRole.ADMIN, ManagerRole.BD_USER, ManagerRole.SERVANT}) - public void setClientPaySurCharge(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager,@PathVariable String clientMoniker, @RequestBody JSONObject config) { - clientManager.setClientQRCodePaySurCharge(manager,clientMoniker, config.getBooleanValue("qrcode_surcharge")); + public void setClientPaySurCharge(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, @PathVariable String clientMoniker, @RequestBody JSONObject config) { + clientManager.setClientQRCodePaySurCharge(manager, clientMoniker, config.getBooleanValue("qrcode_surcharge")); } @ManagerMapping(value = "/{clientMoniker}/gateway_upgrade", method = RequestMethod.PUT, role = {ManagerRole.DEVELOPER}) - public void enableGatewayUpgrade(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager,@PathVariable String clientMoniker, @RequestBody JSONObject config) { - clientManager.enableGatewayUpgrade(manager,clientMoniker, config.getBooleanValue("gateway_upgrade")); + public void enableGatewayUpgrade(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, @PathVariable String clientMoniker, @RequestBody JSONObject config) { + clientManager.enableGatewayUpgrade(manager, clientMoniker, config.getBooleanValue("gateway_upgrade")); } @ManagerMapping(value = "/{clientMoniker}/gateway_alipay_online", method = RequestMethod.PUT, role = {ManagerRole.DEVELOPER}) - public void enableGatewayAlipayOnline(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager,@PathVariable String clientMoniker, @RequestBody JSONObject config) { - clientManager.enableGatewayAlipayOnline(manager,clientMoniker, config.getBooleanValue("gateway_alipay_online")); + public void enableGatewayAlipayOnline(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, @PathVariable String clientMoniker, @RequestBody JSONObject config) { + clientManager.enableGatewayAlipayOnline(manager, clientMoniker, config.getBooleanValue("gateway_alipay_online")); } @ManagerMapping(value = "/{clientMoniker}/api_surcharge", method = RequestMethod.PUT, role = {ManagerRole.OPERATOR, ManagerRole.ADMIN, ManagerRole.BD_USER, ManagerRole.SERVANT}) - public void setClientApiPaySurCharge(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager,@PathVariable String clientMoniker, @RequestBody JSONObject config) { - clientManager.setClientApiPaySurCharge(manager,clientMoniker, config.getBooleanValue("api_surcharge")); + public void setClientApiPaySurCharge(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, @PathVariable String clientMoniker, @RequestBody JSONObject config) { + clientManager.setClientApiPaySurCharge(manager, clientMoniker, config.getBooleanValue("api_surcharge")); } @ManagerMapping(value = "/{clientMoniker}/retail_surcharge", method = RequestMethod.PUT, role = {ManagerRole.OPERATOR, ManagerRole.ADMIN, ManagerRole.BD_USER, ManagerRole.SERVANT}) - public void setClientRetailPaySurCharge(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager,@PathVariable String clientMoniker, @RequestBody JSONObject config) { - clientManager.setClientRetailPaySurCharge(manager,clientMoniker, config.getBooleanValue("retail_surcharge")); + public void setClientRetailPaySurCharge(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, @PathVariable String clientMoniker, @RequestBody JSONObject config) { + clientManager.setClientRetailPaySurCharge(manager, clientMoniker, config.getBooleanValue("retail_surcharge")); } @ManagerMapping(value = "/{clientMoniker}/cbbank_surcharge", method = RequestMethod.PUT, role = {ManagerRole.OPERATOR, ManagerRole.ADMIN, ManagerRole.BD_USER}) - public void setClientCBBankPaySurCharge(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager,@PathVariable String clientMoniker, @RequestBody JSONObject config) { - clientManager.setClientCBBankPaySurCharge(manager,clientMoniker, config.getBooleanValue("cbbank_surcharge")); + public void setClientCBBankPaySurCharge(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, @PathVariable String clientMoniker, @RequestBody JSONObject config) { + clientManager.setClientCBBankPaySurCharge(manager, clientMoniker, config.getBooleanValue("cbbank_surcharge")); } @ManagerMapping(value = "/{clientMoniker}/tax_in_surcharge", method = RequestMethod.PUT, role = {ManagerRole.OPERATOR, ManagerRole.ADMIN}) - public void setClientTaxPayer(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager,@PathVariable String clientMoniker, @RequestBody JSONObject config) { - clientManager.setClientTaxInSurcharge(manager,clientMoniker, config.getBooleanValue("tax_in_surcharge")); + public void setClientTaxPayer(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, @PathVariable String clientMoniker, @RequestBody JSONObject config) { + clientManager.setClientTaxInSurcharge(manager, clientMoniker, config.getBooleanValue("tax_in_surcharge")); } @ManagerMapping(value = "/{clientMoniker}/customer_tax_free", method = RequestMethod.PUT, role = {ManagerRole.OPERATOR}) - public void setClientCustomerTaxFree(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager,@PathVariable String clientMoniker, @RequestBody JSONObject config) { - clientManager.setClientCustomerTaxFree(manager,clientMoniker, config.getBooleanValue("customer_tax_free")); + public void setClientCustomerTaxFree(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, @PathVariable String clientMoniker, @RequestBody JSONObject config) { + clientManager.setClientCustomerTaxFree(manager, clientMoniker, config.getBooleanValue("customer_tax_free")); } @ManagerMapping(value = "/{clientMoniker}/credential_code", method = RequestMethod.PUT, role = {ManagerRole.OPERATOR, ManagerRole.BD_USER}) @@ -283,6 +288,7 @@ public class PartnerManageController { /** * 父商户全局管理子商户 + * * @param clientMoniker * @param pass * @param manager @@ -294,7 +300,7 @@ public class PartnerManageController { @ManagerMapping(value = "/{clientMoniker}/child_each_refund", method = RequestMethod.PUT, role = {ManagerRole.OPERATOR}) public void switchChildEachRefund(@PathVariable String clientMoniker, @RequestBody JSONObject pass, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { - clientManager.switchChildEachRefund(manager, clientMoniker, pass.getBooleanValue("allow")); + clientManager.switchChildEachRefund(manager, clientMoniker, pass.getBooleanValue("allow")); } @ManagerMapping(value = "/{clientMoniker}/channels/{channel}/permission", method = RequestMethod.PUT, role = {ManagerRole.SERVANT, ManagerRole.DEVELOPER}) @@ -328,7 +334,7 @@ public class PartnerManageController { } @ManagerMapping(value = "/{clientMoniker}/reset/refund_pwd", method = RequestMethod.PUT, role = {ManagerRole.OPERATOR, ManagerRole.ADMIN, ManagerRole.DEVELOPER}) - public void changeRefundPwd(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager,@RequestBody JSONObject config) { + public void changeRefundPwd(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, @RequestBody JSONObject config) { clientManager.resetRefundPasswordByManage(clientMoniker, manager, config); } @@ -363,7 +369,7 @@ public class PartnerManageController { return tradeLogService.listOrderRefunds(orderId, null); } - @ManagerMapping(value = "/{clientMoniker}/accounts", method = RequestMethod.GET, role = {ManagerRole.ADMIN, ManagerRole.BD_USER, ManagerRole.OPERATOR, ManagerRole.SERVANT, ManagerRole.DIRECTOR,ManagerRole.DEVELOPER}) + @ManagerMapping(value = "/{clientMoniker}/accounts", method = RequestMethod.GET, role = {ManagerRole.ADMIN, ManagerRole.BD_USER, ManagerRole.OPERATOR, ManagerRole.SERVANT, ManagerRole.DIRECTOR, ManagerRole.DEVELOPER}) public List partnerAccounts(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { return clientManager.listAccounts(manager, clientMoniker); } @@ -411,8 +417,8 @@ public class PartnerManageController { } @ManagerMapping(value = "/{clientMoniker}/skip_clearing", method = RequestMethod.PUT, role = {ManagerRole.ADMIN, ManagerRole.OPERATOR, ManagerRole.FINANCIAL_STAFF}) - public void skipClearing(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager,@PathVariable String clientMoniker, @RequestBody JSONObject skip_clearing) { - clientManager.setSkipClearing(manager,clientMoniker, skip_clearing.getBooleanValue("skip_clearing"),skip_clearing.getString("remark")); + public void skipClearing(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, @PathVariable String clientMoniker, @RequestBody JSONObject skip_clearing) { + clientManager.setSkipClearing(manager, clientMoniker, skip_clearing.getBooleanValue("skip_clearing"), skip_clearing.getString("remark")); } @ManagerMapping(value = "/{clientMoniker}/surcharge_mode", method = RequestMethod.PUT, role = {ManagerRole.ADMIN, ManagerRole.OPERATOR}) @@ -501,7 +507,7 @@ public class PartnerManageController { @RequestParam(required = false) String[] client_ids, @RequestParam(defaultValue = "1") int page, @RequestParam(defaultValue = "10") int limit, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { - return clientManager.listClientDevices(manager, clientMoniker, remark, page, limit,client_type,client_ids); + return clientManager.listClientDevices(manager, clientMoniker, remark, page, limit, client_type, client_ids); } //给商户新增设备 @@ -567,7 +573,7 @@ public class PartnerManageController { @ManagerMapping(value = "/{clientMoniker}/export/aggregate/agreepdf", method = RequestMethod.GET, role = {ManagerRole.ADMIN, ManagerRole.DIRECTOR, ManagerRole.OPERATOR}) public void exportAggregateAgreeFile(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) throws Exception { - clientManager.getAggregateAgreeFile(clientMoniker, manager,false); + clientManager.getAggregateAgreeFile(clientMoniker, manager, false); } @ManagerMapping(value = "/{clientMoniker}/temp/export/pdf", method = RequestMethod.GET, role = {ManagerRole.ADMIN, ManagerRole.BD_USER, ManagerRole.DIRECTOR, ManagerRole.OPERATOR}) @@ -577,7 +583,7 @@ public class PartnerManageController { @ManagerMapping(value = "/{clientMoniker}/import/agreepdf", method = RequestMethod.PUT, role = {ManagerRole.ADMIN, ManagerRole.DIRECTOR, ManagerRole.OPERATOR}) public void importAgreeFile(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, @RequestBody JSONObject source) throws Exception { - clientManager.importAgreeFile(clientMoniker, manager, source.getString("source_agree_file"),false); + clientManager.importAgreeFile(clientMoniker, manager, source.getString("source_agree_file"), false); } @ManagerMapping(value = "/{clientMoniker}/notify/completeAgree", method = RequestMethod.GET, role = {ManagerRole.ADMIN, ManagerRole.OPERATOR}) @@ -628,19 +634,19 @@ public class PartnerManageController { merchantLocationService.updateMerchantLocation(manager, clientMoniker, geoData); } - @ManagerMapping(value = "/{clientMoniker}/wechat_compliance_permission",method = RequestMethod.PUT,role = {ManagerRole.OPERATOR,ManagerRole.ADMIN}) + @ManagerMapping(value = "/{clientMoniker}/wechat_compliance_permission", method = RequestMethod.PUT, role = {ManagerRole.OPERATOR, ManagerRole.ADMIN}) public void wechatCcompliancePermission(@PathVariable String clientMoniker, @RequestBody JSONObject pass, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { clientManager.switchPermission(manager, clientMoniker, "wechat_compliance", pass.getBooleanValue("allow")); } - @ManagerMapping(value = "/{clientMoniker}/local_merchant_permission",method = RequestMethod.PUT,role = {ManagerRole.OPERATOR,ManagerRole.ADMIN}) + @ManagerMapping(value = "/{clientMoniker}/local_merchant_permission", method = RequestMethod.PUT, role = {ManagerRole.OPERATOR, ManagerRole.ADMIN}) public void localMerchantPermission(@PathVariable String clientMoniker, @RequestBody JSONObject pass, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { clientManager.switchPermission(manager, clientMoniker, "local_merchant", pass.getBooleanValue("allow")); } - @ManagerMapping(value = "/{clientMoniker}/list_sub_applices",method = RequestMethod.GET,role = {ManagerRole.OPERATOR,ManagerRole.ADMIN}) + @ManagerMapping(value = "/{clientMoniker}/list_sub_applices", method = RequestMethod.GET, role = {ManagerRole.OPERATOR, ManagerRole.ADMIN}) public List listSubMerchantIdApplys(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { - return clientManager.listSubMerchantIdApplys(manager,clientMoniker); + return clientManager.listSubMerchantIdApplys(manager, clientMoniker); } @ManagerMapping(value = "/{clientMoniker}/list_rpay_sub_applices", method = RequestMethod.GET, role = {ManagerRole.OPERATOR, ManagerRole.ADMIN}) @@ -655,56 +661,57 @@ public class PartnerManageController { @ManagerMapping(value = "/{clientMoniker}/sub_apply", method = RequestMethod.POST, role = {ManagerRole.OPERATOR, ManagerRole.ADMIN}) public String subMerchantApplication(@PathVariable String clientMoniker, @RequestBody SubMerchantIdApply subMerchantIdApply, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { - return clientManager.subMerchantApplication(clientMoniker,subMerchantIdApply,manager); + return clientManager.subMerchantApplication(clientMoniker, subMerchantIdApply, manager); } @ManagerMapping(value = "/{clientMoniker}/register/alipay_gms", method = RequestMethod.POST, role = {ManagerRole.OPERATOR, ManagerRole.ADMIN}) - public void registerAlipayGms(@PathVariable String clientMoniker,@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { + public void registerAlipayGms(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { clientManager.registerAlipayGms(clientMoniker, manager); } @ManagerMapping(value = "/{clientMoniker}/query/alipay_gms", method = RequestMethod.GET, role = {ManagerRole.OPERATOR, ManagerRole.ADMIN}) - public String queryAlipayGmsStatus(@PathVariable String clientMoniker,@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { + public String queryAlipayGmsStatus(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { return clientManager.queryAlipayGmsStatus(clientMoniker, manager); } @ManagerMapping(value = "/{clientMoniker}/register/alipayOnline_gms", method = RequestMethod.POST, role = {ManagerRole.OPERATOR, ManagerRole.ADMIN}) - public void registerAlipayOnlineGms(@PathVariable String clientMoniker,@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { + public void registerAlipayOnlineGms(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { clientManager.registerAlipayOnlineGms(clientMoniker, manager); } @ManagerMapping(value = "/{clientMoniker}/query/alipayOnline_gms", method = RequestMethod.GET, role = {ManagerRole.OPERATOR, ManagerRole.ADMIN}) - public String queryAlipayOnlineGmsStatus(@PathVariable String clientMoniker,@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { + public String queryAlipayOnlineGmsStatus(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { return clientManager.queryAlipayOnlineGmsStatus(clientMoniker, manager); } @ManagerMapping(value = "/{clientMoniker}/query/alipay_gms_json", method = RequestMethod.GET, role = {ManagerRole.OPERATOR, ManagerRole.ADMIN}) - public JSONObject queryAlipayGmsJson(@PathVariable String clientMoniker,@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { + public JSONObject queryAlipayGmsJson(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { return clientManager.queryAlipayGmsJson(clientMoniker, manager); } @ManagerMapping(value = "/{clientMoniker}/query/alipayOnline_gms_json", method = RequestMethod.GET, role = {ManagerRole.OPERATOR, ManagerRole.ADMIN}) - public JSONObject queryAlipayOnlineGmsJson(@PathVariable String clientMoniker,@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { + public JSONObject queryAlipayOnlineGmsJson(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { return clientManager.queryAlipayOnlineGmsJson(clientMoniker, manager); } - @ManagerMapping(value = "/{clientMoniker}/get_merchant_ids",method = RequestMethod.GET,role = {ManagerRole.OPERATOR,ManagerRole.ADMIN}) + @ManagerMapping(value = "/{clientMoniker}/get_merchant_ids", method = RequestMethod.GET, role = {ManagerRole.OPERATOR, ManagerRole.ADMIN}) public List getMerchantIds(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { - return clientManager.listMerchantIds(clientMoniker,manager); + return clientManager.listMerchantIds(clientMoniker, manager); } - @ManagerMapping(value = "/{clientMoniker}/get_sub_merchant_id_logs",method = RequestMethod.GET,role = {ManagerRole.OPERATOR}) + @ManagerMapping(value = "/{clientMoniker}/get_sub_merchant_id_logs", method = RequestMethod.GET, role = {ManagerRole.OPERATOR}) public List getClientSubMerchantIdLogs(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { - return clientManager.getClientSubMerchantIdLogs(clientMoniker,manager); + return clientManager.getClientSubMerchantIdLogs(clientMoniker, manager); } - @ManagerMapping(value = "/unsub/{clientMoniker}",method = RequestMethod.PUT,role = {ManagerRole.OPERATOR}) + + @ManagerMapping(value = "/unsub/{clientMoniker}", method = RequestMethod.PUT, role = {ManagerRole.OPERATOR}) public void addSub(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { - clientManager.addSub(clientMoniker,manager); + clientManager.addSub(clientMoniker, manager); } - @ManagerMapping(value = "/unsub/{clientMoniker}",method = RequestMethod.DELETE,role = {ManagerRole.OPERATOR}) + @ManagerMapping(value = "/unsub/{clientMoniker}", method = RequestMethod.DELETE, role = {ManagerRole.OPERATOR}) public void removeSub(@PathVariable String clientMoniker, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { - clientManager.removeSub(clientMoniker,manager); + clientManager.removeSub(clientMoniker, manager); } @ManagerMapping(value = "/{clientMoniker}/hf", method = RequestMethod.PUT, role = {ManagerRole.ADMIN, ManagerRole.OPERATOR}) @@ -718,32 +725,32 @@ public class PartnerManageController { } @ManagerMapping(value = "/{clientMoniker}/{channel}", method = RequestMethod.PUT, role = {ManagerRole.ADMIN, ManagerRole.OPERATOR}) - public void switchGateWayLinkPermission(@PathVariable String clientMoniker, @PathVariable String channel,@RequestBody JSONObject pass, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { - clientManager.switchGatewayLink(manager, clientMoniker, channel,pass.getBooleanValue("allow")); + public void switchGateWayLinkPermission(@PathVariable String clientMoniker, @PathVariable String channel, @RequestBody JSONObject pass, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { + clientManager.switchGatewayLink(manager, clientMoniker, channel, pass.getBooleanValue("allow")); } @ManagerMapping(value = "/{clientMoniker}/{channel}/email_notice", method = RequestMethod.PUT, role = {ManagerRole.OPERATOR, ManagerRole.BD_USER}) - public void switchGatewayEmailNotice(@PathVariable String clientMoniker, @PathVariable String channel,@RequestBody JSONObject pass, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { - clientManager.switchPermission(manager, clientMoniker,"enable_"+channel+"_email_notice", pass.getBooleanValue("allow")); + public void switchGatewayEmailNotice(@PathVariable String clientMoniker, @PathVariable String channel, @RequestBody JSONObject pass, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { + clientManager.switchPermission(manager, clientMoniker, "enable_" + channel + "_email_notice", pass.getBooleanValue("allow")); } @ManagerMapping(value = "/{clientMoniker}/registRpaySubMerchantId", method = RequestMethod.POST, role = {ManagerRole.OPERATOR, ManagerRole.ADMIN}) - public void subRpayMerchantApplication(@PathVariable String clientMoniker,@RequestBody JSONObject merchantInfo,@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { - clientManager.subRpayMerchantApplication(clientMoniker, merchantInfo,manager); + public void subRpayMerchantApplication(@PathVariable String clientMoniker, @RequestBody JSONObject merchantInfo, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { + clientManager.subRpayMerchantApplication(clientMoniker, merchantInfo, manager); } @ManagerMapping(value = "/{clientMoniker}/registYeepaySubMerchantId", method = RequestMethod.POST, role = {ManagerRole.OPERATOR, ManagerRole.ADMIN}) - public void subYeepayMerchantApplication(@PathVariable String clientMoniker,@RequestBody JSONObject merchantInfo,@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { - clientManager.subYeepayMerchantApplication(clientMoniker, merchantInfo,manager); + public void subYeepayMerchantApplication(@PathVariable String clientMoniker, @RequestBody JSONObject merchantInfo, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { + clientManager.subYeepayMerchantApplication(clientMoniker, merchantInfo, manager); } @ManagerMapping(value = "/{clientMoniker}/updateYeepaySubMerchantId", method = RequestMethod.POST, role = {ManagerRole.OPERATOR, ManagerRole.ADMIN}) - public void reSubYeepayMerchantApplication(@PathVariable String clientMoniker,@RequestBody JSONObject merchantInfo,@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { - clientManager.reSubYeepayMerchantApplication(clientMoniker, merchantInfo,manager); + public void reSubYeepayMerchantApplication(@PathVariable String clientMoniker, @RequestBody JSONObject merchantInfo, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { + clientManager.reSubYeepayMerchantApplication(clientMoniker, merchantInfo, manager); } @RequestMapping(value = "/compliance", method = RequestMethod.GET) - @RequireManager(role = { ManagerRole.OPERATOR}) + @RequireManager(role = {ManagerRole.OPERATOR}) public JSONObject lisPartnersByCompliance(@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager, PartnerQuery query) { return clientManager.comListPartnerSelection(manager, query); } @@ -765,8 +772,8 @@ public class PartnerManageController { } @ManagerMapping(value = "/{clientMoniker}/addYeepaySubMerchantId", method = RequestMethod.POST, role = {ManagerRole.OPERATOR, ManagerRole.ADMIN}) - public void subYeepayMerchantAdd(@PathVariable String clientMoniker,@RequestBody JSONObject merchantInfo,@ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { - clientManager.subYeepayMerchantAdd(clientMoniker, merchantInfo,manager); + public void subYeepayMerchantAdd(@PathVariable String clientMoniker, @RequestBody JSONObject merchantInfo, @ModelAttribute(CommonConsts.MANAGER_STATUS) JSONObject manager) { + clientManager.subYeepayMerchantAdd(clientMoniker, merchantInfo, manager); } @RequestMapping(value = "/{clientMoniker}/cb_bankpay/link/pc", method = RequestMethod.GET) @@ -777,11 +784,12 @@ public class PartnerManageController { /** * 商户设置单独的网银和快捷通道 + * * @param clientMoniker * @param channelKey * @throws IOException */ - @ManagerMapping(value = "/{clientMoniker}/cb_bankpay/{channelKey}/channel_id", method = RequestMethod.PUT, role = {ManagerRole.ADMIN, ManagerRole.OPERATOR}) + @ManagerMapping(value = "/{clientMoniker}/cb_bankpay/{channelKey}/channel_id", method = RequestMethod.PUT, role = {ManagerRole.ADMIN, ManagerRole.OPERATOR}) public void switchPartnerCBChannelConfig(@PathVariable String clientMoniker, @PathVariable String channelKey, @RequestBody JSONObject channel) { clientManager.partnerCBChannelConfig(clientMoniker, channelKey, channel.getString("channel_id")); } diff --git a/src/main/java/au/com/royalpay/payment/manage/support/serverless/ServerlessFunctionTrigger.java b/src/main/java/au/com/royalpay/payment/manage/support/serverless/ServerlessFunctionTrigger.java new file mode 100644 index 000000000..8d5e9fdb4 --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/support/serverless/ServerlessFunctionTrigger.java @@ -0,0 +1,11 @@ +package au.com.royalpay.payment.manage.support.serverless; + +import com.alibaba.fastjson.JSONObject; + +/** + * Create by davep at 2019-08-08 15:56 + */ +public interface ServerlessFunctionTrigger { + + JSONObject triggerFunction(String function,JSONObject params); +} diff --git a/src/main/java/au/com/royalpay/payment/manage/support/serverless/qcloud/QCloudServerlessTrigger.java b/src/main/java/au/com/royalpay/payment/manage/support/serverless/qcloud/QCloudServerlessTrigger.java new file mode 100644 index 000000000..4e680c42a --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/support/serverless/qcloud/QCloudServerlessTrigger.java @@ -0,0 +1,63 @@ +package au.com.royalpay.payment.manage.support.serverless.qcloud; + +import au.com.royalpay.payment.manage.support.serverless.ServerlessFunctionTrigger; +import au.com.royalpay.payment.manage.support.serverless.qcloud.support.ServerLessFunctionInvokeRequest; +import au.com.royalpay.payment.tools.exceptions.ServerErrorException; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.StringHttpMessageConverter; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import java.nio.charset.StandardCharsets; + +/** + * Create by davep at 2019-08-12 9:31 + */ +@Service +public class QCloudServerlessTrigger implements ServerlessFunctionTrigger { + private Logger logger = LoggerFactory.getLogger(getClass()); + private RestTemplate restTemplate; + private String secretId; + private String secretKey; + private String region; + + public QCloudServerlessTrigger(@Value("${qcloud.secret-id}") String secretId, + @Value("${qcloud.secret-key}") String secretKey, + @Value("${qcloud.scf.region}") String region) { + this.secretId = secretId; + this.secretKey = secretKey; + this.region = region; + this.restTemplate = new RestTemplateBuilder() + .messageConverters(new StringHttpMessageConverter(StandardCharsets.UTF_8)) + .build(); + } + + + @Override + public JSONObject triggerFunction(String function, JSONObject params) { + ServerLessFunctionInvokeRequest request = new ServerLessFunctionInvokeRequest(secretId, secretKey, region, function, params); + ResponseEntity resp = restTemplate.exchange(request.request(), String.class); + JSONObject data = JSON.parseObject(resp.getBody()); + JSONObject response = data.getJSONObject("Response"); + String requestId = response.getString("RequestId"); + JSONObject result = response.getJSONObject("Result"); + int invokeResult = result.getIntValue("InvokeResult"); + if (invokeResult != 0) { + String errMsg = result.getString("ErrMsg"); + logger.error("Invoking function [{}] failed,request id={},invoke result={},errMsg={}", function, requestId, invokeResult, errMsg); + throw new ServerErrorException("Invoke function " + function + " failed:[" + errMsg + "]"); + } else { + String retMsg = result.getString("RetMsg"); + return StringUtils.isNotEmpty(retMsg) ? JSON.parseObject(retMsg) : null; + } + } + + +} diff --git a/src/main/java/au/com/royalpay/payment/manage/support/serverless/qcloud/support/QCloudV3Request.java b/src/main/java/au/com/royalpay/payment/manage/support/serverless/qcloud/support/QCloudV3Request.java new file mode 100644 index 000000000..1adec2cd1 --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/support/serverless/qcloud/support/QCloudV3Request.java @@ -0,0 +1,135 @@ +package au.com.royalpay.payment.manage.support.serverless.qcloud.support; + +import au.com.royalpay.payment.tools.exceptions.ServerErrorException; +import org.apache.commons.codec.binary.Hex; +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.lang3.StringUtils; +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.HttpMethod; +import org.springframework.http.RequestEntity; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.util.UriComponentsBuilder; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * Create by davep at 2019-08-12 15:06 + */ +public abstract class QCloudV3Request { + private static Logger logger = LoggerFactory.getLogger(QCloudV3Request.class); + private static final String ALGORITHM = "TC3-HMAC-SHA256"; + private String secretId; + private String secretKey; + private String region; + private MultiValueMap headers = new LinkedMultiValueMap<>(); + + + public QCloudV3Request(String secretId, String secretKey, String region) { + this.secretId = secretId; + this.secretKey = secretKey; + this.region = region; + headers.add("host", host()); + headers.add("content-type", contentType()); + } + + protected abstract String host(); + + protected abstract String uri(); + + protected abstract HttpMethod method(); + + protected abstract String action(); + + protected abstract String version(); + + protected abstract String contentType(); + + protected abstract String requestPayload(); + + protected abstract String queryStringParams(); + + protected String service() { + return StringUtils.substringBefore(host(), "."); + } + + public void setHeader(String name, String value) { + headers.add(name, value); + } + + public RequestEntity request() { + UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl("https://" + host() + uri()); + String queryStr = queryStringParams(); + if (StringUtils.isNotEmpty(queryStr)) { + uriBuilder = uriBuilder.query(queryStr); + } + URI url = uriBuilder.build(false).toUri(); + RequestEntity.BodyBuilder builder = RequestEntity.method(method(), url); + MultiValueMap signHeaders = buildSignature(); + for (Map.Entry> entry : signHeaders.entrySet()) { + builder = builder.header(entry.getKey(), entry.getValue().toArray(new String[0])); + } + return builder.body(requestPayload()); + } + + private MultiValueMap buildSignature() { + String timestamp = System.currentTimeMillis() / 1000 + ""; + String date = DateTime.now(DateTimeZone.UTC).toString("yyyy-MM-dd"); + // ************* 步骤 1:拼接规范请求串 ************* + String httpRequestMethod = method().name(); + String canonicalUri = uri(); + String canonicalQueryString = queryStringParams(); + String canonicalHeaders = headers.entrySet().stream() + .flatMap(nameEntry -> nameEntry.getValue().stream() + .map(v -> nameEntry.getKey().toLowerCase() + ":" + v + "\n")) + .sorted() + .collect(Collectors.joining()); + String signedHeaders = headers.keySet().stream().map(String::toLowerCase).sorted().collect(Collectors.joining(";")); + String hashedRequestPayload = DigestUtils.sha256Hex(requestPayload()); + String canonicalRequest = String.join("\n", httpRequestMethod, canonicalUri, canonicalQueryString, canonicalHeaders, signedHeaders, hashedRequestPayload); + logger.info("request:\n{}", canonicalRequest); + // ************* 步骤 2:拼接待签名字符串 ************* + String credentialScope = date + "/" + service() + "/tc3_request"; + String hashedCanonicalRequest = DigestUtils.sha256Hex(canonicalRequest.getBytes(StandardCharsets.UTF_8)); + String stringToSign = String.join("\n", ALGORITHM, timestamp, credentialScope, hashedCanonicalRequest); + logger.info("to sign:\n{}", stringToSign); + // ************* 步骤 3:计算签名 ************* + byte[] secretDate = sign256(("TC3" + secretKey).getBytes(StandardCharsets.UTF_8), date); + byte[] secretService = sign256(secretDate, service()); + byte[] secretSigning = sign256(secretService, "tc3_request"); + String signature = Hex.encodeHexString(sign256(secretSigning, stringToSign)).toLowerCase(); + String authorization = String.format("%s Credential=%s/%s, SignedHeaders=%s, Signature=%s", + ALGORITHM, secretId, credentialScope, signedHeaders, signature); + + MultiValueMap signHeaders = new LinkedMultiValueMap<>(headers); + signHeaders.set("Authorization", authorization); + signHeaders.set("X-TC-Action", action()); + signHeaders.set("X-TC-Timestamp", timestamp); + signHeaders.set("X-TC-Version", version()); + signHeaders.set("X-TC-Region", region); + return signHeaders; + } + + private static byte[] sign256(byte[] key, String msg) { + try { + Mac mac = Mac.getInstance("HmacSHA256"); + SecretKeySpec secretKeySpec = new SecretKeySpec(key, mac.getAlgorithm()); + mac.init(secretKeySpec); + return mac.doFinal(msg.getBytes(StandardCharsets.UTF_8)); + } catch (NoSuchAlgorithmException | InvalidKeyException e) { + logger.error(e.getMessage(), e); + throw new ServerErrorException(e); + } + } +} diff --git a/src/main/java/au/com/royalpay/payment/manage/support/serverless/qcloud/support/ServerLessFunctionInvokeRequest.java b/src/main/java/au/com/royalpay/payment/manage/support/serverless/qcloud/support/ServerLessFunctionInvokeRequest.java new file mode 100644 index 000000000..c4302a0cc --- /dev/null +++ b/src/main/java/au/com/royalpay/payment/manage/support/serverless/qcloud/support/ServerLessFunctionInvokeRequest.java @@ -0,0 +1,62 @@ +package au.com.royalpay.payment.manage.support.serverless.qcloud.support; + +import com.alibaba.fastjson.JSONObject; +import org.springframework.http.HttpMethod; +import org.springframework.util.MimeTypeUtils; + +/** + * Create by davep at 2019-08-12 17:13 + */ +public class ServerLessFunctionInvokeRequest extends QCloudV3Request { + private final String functionName; + private final JSONObject clientContext; + + public ServerLessFunctionInvokeRequest(String secretId, String secretKey, String region, String functionName, JSONObject clientContext) { + super(secretId, secretKey, region); + this.functionName = functionName; + this.clientContext = clientContext == null ? new JSONObject() : clientContext; + } + + @Override + protected String host() { + return "scf.tencentcloudapi.com"; + } + + @Override + protected String uri() { + return "/"; + } + + @Override + protected HttpMethod method() { + return HttpMethod.POST; + } + + @Override + protected String action() { + return "Invoke"; + } + + @Override + protected String version() { + return "2018-04-16"; + } + + @Override + protected String contentType() { + return MimeTypeUtils.APPLICATION_JSON_VALUE; + } + + @Override + protected String requestPayload() { + JSONObject data = new JSONObject(); + data.put("FunctionName", functionName); + data.put("ClientContext", clientContext.toJSONString()); + return data.toJSONString(); + } + + @Override + protected String queryStringParams() { + return ""; + } +} diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index d177ae586..b2810ea7e 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -144,3 +144,6 @@ app.hanyin-secure.sftp-port=28480 app.hanyin-secure.sftp-username=royalpay app.hanyin-secure.sftp-pwd=royalpay +qcloud.secret-id=AKIDlHdjgWzZliPvBauZFfrnW0MaZOyHdTPz +qcloud.secret-key=YswoQDsIZfWEqEAEvMXS8Yic84lFn9Jp +qcloud.scf.region=ap-hongkong \ No newline at end of file diff --git a/src/main/resources/templates/mail/subscribe_mail.html b/src/main/resources/templates/mail/subscribe_mail.html new file mode 100644 index 000000000..4c763330d --- /dev/null +++ b/src/main/resources/templates/mail/subscribe_mail.html @@ -0,0 +1,7 @@ + + +
+ +
+ + diff --git a/src/main/ui/static/commons/filters/commonFilters.js b/src/main/ui/static/commons/filters/commonFilters.js index af6d51e3e..e6452c454 100644 --- a/src/main/ui/static/commons/filters/commonFilters.js +++ b/src/main/ui/static/commons/filters/commonFilters.js @@ -71,6 +71,18 @@ define(['../app', 'jquery'], function (app, $) { } }); + var ausMchCategory = []; + $.ajax({ + url: '/static/data/aus_mch_category.json', + method: 'GET', + async: false, + dataType: 'json', + success: function (data) { + ausMchCategory = data; + + } + }); + app.filter('partner_state', ['stateMap', function (stateMap) { return function (stateValue) { var stateLabel = ''; @@ -247,4 +259,21 @@ define(['../app', 'jquery'], function (app, $) { return sectorLabel; } }]); + + app.filter('aus_mch_category', ['$http', function ($http) { + return function (industryCode) { + var categoryLabel = ''; + var industryLabel = ''; + angular.forEach(ausMchCategory, function (category) { + angular.forEach(category.children, function (categoryChildren1) { + if (categoryChildren1.mccCode == industryCode) { + industryLabel = categoryChildren1.label; + categoryLabel = category.label; + } + }); + }); + return { categoryLabel:categoryLabel, industryLabel: industryLabel }; + } + + }]); }); diff --git a/src/main/ui/static/data/aus_mch_category.json b/src/main/ui/static/data/aus_mch_category.json new file mode 100644 index 000000000..e5359a3c0 --- /dev/null +++ b/src/main/ui/static/data/aus_mch_category.json @@ -0,0 +1,1093 @@ +[{ + "label": "Agricultural Services", + "children": [{ + "label": "Agricultural Cooperatives", + "mccCode": "10001" + }] +}, { + "label": "Associations", + "children": [{ + "label": "Associations-Civic, Social, and Fraternal", + "mccCode": "20001" + }, { + "label": "Automobile Associations", + "mccCode": "20003" + }, { + "label": "Buying/Shopping Clubs, Services", + "mccCode": "20004" + }, { + "label": "Clubs-Cntry, Mbrship(Athlet, Rec, Sprts, Private Golf)", + "mccCode": "20005" + }, { + "label": "Organizations, Membership-Not Elsewhere Classified", + "mccCode": "20006" + }, { + "label": "Organizations, Political", + "mccCode": "20007" + }] +}, { + "label": "Automotive & Transport", + "children": [{ + "label": "Air Carriers, Airlines-Not Elsewhere Classified", + "mccCode": "30001" + }, { + "label": "Airports, Airport Terminals, Flying Fields", + "mccCode": "30002" + }, { + "label": "Auto & Truck Dlrs-Sales, Svc, Reprs, Prts, & Leasing", + "mccCode": "30003" + }, { + "label": "Auto Store, Home Supply Stores", + "mccCode": "30004" + }, { + "label": "Automobile and Truck Dealers-(Used Only)-Sales", + "mccCode": "30005" + }, { + "label": "Automobile Parking Lots and Garages", + "mccCode": "30006" + }, { + "label": "Automotive Body Repair Shops", + "mccCode": "30007" + }, { + "label": "Automotive Paint Shops", + "mccCode": "30008" + }, { + "label": "Automotive Parts, Accessories Stores", + "mccCode": "30009" + }, { + "label": "Automotive Service Shops", + "mccCode": "30010" + }, { + "label": "Automotive Tire Stores", + "mccCode": "30011" + }, { + "label": "Boat Dealers", + "mccCode": "30012" + }, { + "label": "Bridge and Road Fees, Tolls", + "mccCode": "30013" + }, { + "label": "Bus Lines", + "mccCode": "30014" + }, { + "label": "Camper Dealers, Recreational and Utility Trailers", + "mccCode": "30015" + }, { + "label": "Car Washes", + "mccCode": "30016" + }, { + "label": "Courier Svc-Air & Ground, Freight Forwarders", + "mccCode": "30017" + }, { + "label": "Cruise Lines", + "mccCode": "30018" + }, { + "label": "Freight Carrier, Trucking-Lcl/Lng Dist, Mvg/Storage", + "mccCode": "30019" + }, { + "label": "Fuel Dispenser, Automated", + "mccCode": "30020" + }, { + "label": "Limousines and Taxicabs", + "mccCode": "30021" + }, { + "label": "Marinas, Marine Service/Supplies", + "mccCode": "30022" + }, { + "label": "Misc/Auto/Aircraft/Farm Equip-Not Elsewhere Class", + "mccCode": "30023" + }, { + "label": "Motor Home Dealers", + "mccCode": "30024" + }, { + "label": "Motor Vehicle Supplies and New Parts", + "mccCode": "30025" + }, { + "label": "Motorcycle Shops and Dealers", + "mccCode": "30026" + }, { + "label": "Passenger Railways", + "mccCode": "30027" + }, { + "label": "Petroleum and Petroleum Products", + "mccCode": "30028" + }, { + "label": "Railroads-Freight", + "mccCode": "30029" + }, { + "label": "Service Stations With Or Without Ancillary Service", + "mccCode": "30030" + }, { + "label": "Snowmobile Dealers", + "mccCode": "30031" + }, { + "label": "Tire Retreading and Repair Shops", + "mccCode": "30032" + }, { + "label": "Towing Services", + "mccCode": "30033" + }, { + "label": "Transportation Services-Not Elsewhere Classified", + "mccCode": "30034" + }, { + "label": "Transprtn-Subrbn & Local Comtr Psngr, Incl Ferries", + "mccCode": "30035" + }] +}, { + "label": "Adult", + "children": [{ + "label": "Dating and Escort Services", + "mccCode": "30036" + }, { + "label": "Other Adult Services", + "mccCode": "30037" + }] +}, { + "label": "Business Services", + "children": [{ + "label": "Advertising Services", + "mccCode": "30038" + }, { + "label": "Automobile Rental Agency-Not Elsewhere Classified", + "mccCode": "30039" + }, { + "label": "Business Services-Not Elsewhere Classified", + "mccCode": "30040" + }, { + "label": "Consulting, Management and Public Relations Svcs", + "mccCode": "30041" + }, { + "label": "Consumer Credit Reporting Agencies", + "mccCode": "30042" + }, { + "label": "Detectve/Protectve Agncy, Security Srvs, Armor Cars", + "mccCode": "30043" + }, { + "label": "Employment Agencies, Temporary Help Services", + "mccCode": "30044" + }, { + "label": "Stenographic and Secretarial Support Services", + "mccCode": "30045" + }] +}, { + "label": "Charity & Social", + "children": [{ + "label": "Organizations, Charitable and Social Services", + "mccCode": "40001" + }] +}, { + "label": "Child Care", + "children": [{ + "label": "Child Care Services", + "mccCode": "50001" + }] +}, { + "label": "Cleaning", + "children": [{ + "label": "Carpet and Upholstery Cleaning", + "mccCode": "60001" + }, { + "label": "Cleaning and Maintenance, Janitorial Services", + "mccCode": "60002" + }, { + "label": "Cleaning, Garment and Laundry Services", + "mccCode": "60003" + }, { + "label": "Dry Cleaners", + "mccCode": "60004" + }, { + "label": "Hat Cleaning Shops, Shoe Repair Shops, Shoe Shine", + "mccCode": "60005" + }, { + "label": "Laundry Services-Family and Commerical", + "mccCode": "60006" + }] +}, { + "label": "Counselling", + "children": [{ + "label": "Debt, Marriage, Personal-Counseling Service", + "mccCode": "70001" + }] +}, { + "label": "Education", + "children": [{ + "label": "Child Care Services", + "mccCode": "80001" + }, { + "label": "Colleges, Univ, Pro Schools, Junior Colleges", + "mccCode": "80002" + }, { + "label": "Dance Halls, Schools and Studios", + "mccCode": "80003" + }, { + "label": "Schools & Educational Svc-Not Elsewhere Classified", + "mccCode": "80004" + }, { + "label": "Schools, Business and Secretarial", + "mccCode": "80005" + }, { + "label": "Schools, Correspondence", + "mccCode": "80006" + }, { + "label": "Schools, Elementary and Secondary", + "mccCode": "80007" + }, { + "label": "Schools, Trade and Vocational", + "mccCode": "80008" + }] +}, { + "label": "Emergency Services", + "children": [{ + "label": "Ambulance Services", + "mccCode": "90001" + }] +}, { + "label": "Entertainment", + "children": [{ + "label": "Amusement Parks, Carnivals, Circus, Fortune Tellers", + "mccCode": "100001" + }, { + "label": "Aquariums, Dolphinariums and Seaquariums", + "mccCode": "100002" + }, { + "label": "Bands, Orchestras, & Misc Entrtnrs-Not Elswhr Clas", + "mccCode": "100003" + }, { + "label": "Clubs-Cntry, Mbrship(Athlet, Rec, Sprts, Private Golf)", + "mccCode": "100004" + }, { + "label": "Dance Halls, Schools and Studios", + "mccCode": "100005" + }, { + "label": "Gambling Transactions", + "mccCode": "100006" + }, { + "label": "Motion Picture Theaters", + "mccCode": "100007" + }, { + "label": "Motion Picture/Video Tape Production/Distribution", + "mccCode": "100008" + }, { + "label": "Pool and Billiard Establishments", + "mccCode": "100009" + }, { + "label": "Recreation Services-Not Elsewhere Classified", + "mccCode": "100010" + }, { + "label": "Theatrical Producers(Excl Motion Pix), Ticket Agncy", + "mccCode": "100011" + }, { + "label": "Tourist Attractions and Exhibits", + "mccCode": "100012" + }, { + "label": "Video Amusement Game Supplies", + "mccCode": "100013" + }, { + "label": "Video Entertainment Rental Stores", + "mccCode": "100014" + }, { + "label": "Video Game Arcades/Establishments", + "mccCode": "100015" + }] +}, { + "label": "Entertainment Venues", + "children": [{ + "label": "Bar, Lounge, Disco, Nightclub, Tavern-Alcoholic Drinks", + "mccCode": "110001" + }, { + "label": "Bowling Alleys", + "mccCode": "110002" + }, { + "label": "Motion Picture Theaters", + "mccCode": "110003" + }, { + "label": "Pool and Billiard Establishments", + "mccCode": "110004" + }] +}, { + "label": "Financial", + "children": [{ + "label": "Automated Cash Disbursements-Customer Financial Institution", + "mccCode": "120001" + }, { + "label": "Consumer Credit Reporting Agencies", + "mccCode": "120002" + }, { + "label": "Foreign Exchange", + "mccCode": "120003" + }, { + "label": "Insurance Sales,Underwriting and Premiums", + "mccCode": "120004" + }, { + "label": "Manual Cash Disbursements-Customer Financial Institution", + "mccCode": "120005" + }, { + "label": "Merchandise and Services-Customer Financial Institution", + "mccCode": "120006" + }, { + "label": "Money Transfer", + "mccCode": "120007" + }, { + "label": "Quasi Cash-Merchant", + "mccCode": "120008" + }, { + "label": "Securities-Brokers/Dealers", + "mccCode": "120009" + }, { + "label": "Tax Preparation Service", + "mccCode": "120010" + }] +}, { + "label": "Food/Takeway", + "children": [{ + "label": "Caterers", + "mccCode": "120011" + }, { + "label": "Eating Places, Restaurants", + "mccCode": "120012" + }, { + "label": "Fast Food Restaurants", + "mccCode": "120013" + }] +}, { + "label": "Funeral", + "children": [{ + "label": "Funeral Service and Crematories", + "mccCode": "130001" + }] +}, { + "label": "Government Services", + "children": [{ + "label": "Bail and Bond Payments", + "mccCode": "140001" + }, { + "label": "Court Costs Including Alimony and Child Support", + "mccCode": "140002" + }, { + "label": "Fines", + "mccCode": "140003" + }, { + "label": "Government Services-Not Elsewhere Classified", + "mccCode": "140004" + }, { + "label": "Postal Services-Government Only", + "mccCode": "140005" + }, { + "label": "Tax Payments", + "mccCode": "140006" + }] +}, { + "label": "Health & Beauty", + "children": [{ + "label": "Barber and Beauty Shops", + "mccCode": "150001" + }, { + "label": "Hairdresser & Hair Salon", + "mccCode": "150002" + }, { + "label": "Health and Beauty Spas", + "mccCode": "150003" + }, { + "label": "Make Up & Make Up Artists", + "mccCode": "150004" + }, { + "label": "Massage Parlors", + "mccCode": "150005" + }, { + "label": "Nail Beauty", + "mccCode": "150006" + }, { + "label": "Personal Training", + "mccCode": "150007" + }, { + "label": "Personal Training & Exercise", + "mccCode": "150008" + }] +}, { + "label": "Holiday/Tourism", + "children": [{ + "label": "Campgrounds and Trailer Parks", + "mccCode": "160001" + }, { + "label": "Lodging-Hotels, Motels, Resorts-Not Classified", + "mccCode": "160002" + }, { + "label": "Recreational and Sporting Camps", + "mccCode": "160003" + }, { + "label": "Timeshares", + "mccCode": "160004" + }, { + "label": "Tourist Attractions and Exhibits", + "mccCode": "160005" + }, { + "label": "Travel Agencies and Tour Operators", + "mccCode": "160006" + }] +}, { + "label": "IT Services", + "children": [{ + "label": "Comp Programing, Data Prcsng,Intgrtd Sys Dsgn Srvs", + "mccCode": "170001" + }, { + "label": "Computer Main/Repair/Services Not Elsewhere Class", + "mccCode": "170002" + }, { + "label": "Computer Software Stores", + "mccCode": "170003" + }, { + "label": "Computers, Computer Peripheral Equipment, Software", + "mccCode": "170004" + }, { + "label": "Electronic Sales", + "mccCode": "170005" + }, { + "label": "Information Retrieval Services", + "mccCode": "170006" + }] +}, { + "label": "Legal", + "children": [{ + "label": "Attorneys, Legal Services", + "mccCode": "180001" + }, { + "label": "Bail and Bond Payments", + "mccCode": "180002" + }, { + "label": "Court Costs Including Alimony and Child Support", + "mccCode": "180003" + }, { + "label": "Fines", + "mccCode": "180004" + }] +}, { + "label": "Medical", + "children": [{ + "label": "Chemist Or Pharmacies", + "mccCode": "190001" + }, { + "label": "Chiropodists, Podiatrists", + "mccCode": "190002" + }, { + "label": "Chiropractors", + "mccCode": "190003" + }, { + "label": "Dentists, Orthodontists", + "mccCode": "190004" + }, { + "label": "Doctors-Not Elsewhere Classified", + "mccCode": "190005" + }, { + "label": "Drugs, Drup Proprietaries and Druggist's Supplies", + "mccCode": "190006" + }, { + "label": "Health Practitioners, Medical Srvcs-Not Elsewhere", + "mccCode": "190007" + }, { + "label": "Hearing Aids-Sales, Service, Supply Stores", + "mccCode": "190008" + }, { + "label": "Hospitals", + "mccCode": "190009" + }, { + "label": "Medical and Dental Laboratories", + "mccCode": "190010" + }, { + "label": "Nursing and Personal Care Facilities", + "mccCode": "190011" + }, { + "label": "Opticians, Optical Goods & Eyeglasses", + "mccCode": "190012" + }, { + "label": "Optometrists, Ophthalmologists", + "mccCode": "190013" + }, { + "label": "Orthopedic Goods-Artificial Limb Stores", + "mccCode": "190014" + }, { + "label": "Osteopathic Physicians", + "mccCode": "190015" + }] +}, { + "label": "Miscellaneous", + "children": [{ + "label": "Fuel Dealers-Coal, Fuel Oil, Liq Petroleum, Wood", + "mccCode": "200001" + }, { + "label": "Salvage and Wrecking Yards", + "mccCode": "200002" + }, { + "label": "Stamp & Coin Stores-Philatelic & Numismatic Supply", + "mccCode": "200003" + }] +}, { + "label": "Music", + "children": [{ + "label": "Bands, Orchestras, & Misc Entrtnrs-Not Elswhr Clas", + "mccCode": "210001" + }, { + "label": "Dance Halls, Schools and Studios", + "mccCode": "210002" + }] +}, { + "label": "Photography", + "children": [{ + "label": "Photographic Studios", + "mccCode": "220001" + }] +}, { + "label": "Photography & Printing", + "children": [{ + "label": "Commercial Art, Graphics, Photography", + "mccCode": "220002" + }, { + "label": "Miscellaneous Publishing and Printing", + "mccCode": "220003" + }, { + "label": "Photo Developing, Photofinishing Laboratories", + "mccCode": "220004" + }, { + "label": "Quick Copy, Reproduction and Blueprinting Services", + "mccCode": "220005" + }] +}, { + "label": "Profesional Services", + "children": [{ + "label": "Accounting, Auditing and Bookkeeping Services", + "mccCode": "230001" + }, { + "label": "Architectural, Engineering and Surveying Services", + "mccCode": "230002" + }, { + "label": "Professional Services-Not Elsewhere Classified", + "mccCode": "230003" + }, { + "label": "Tax Preparation Service", + "mccCode": "230004" + }] +}, { + "label": "Real Estate", + "children": [{ + "label": "Real Estate Agents and Managers-Rentals", + "mccCode": "240001" + }] +}, { + "label": "Religious / Spiritual", + "children": [{ + "label": "Organizations, Religious", + "mccCode": "250001" + }, { + "label": "Religious Goods Stores", + "mccCode": "250002" + }] +}, { + "label": "Rental & Hire", + "children": [{ + "label": "Boat Leases and Boat Rentals", + "mccCode": "260001" + }, { + "label": "Clothing Rental-Costumes,Uniforms,Formal Wear", + "mccCode": "260002" + }, { + "label": "Equipment Rental&Leasing Svs, Furnture/Tool Rental", + "mccCode": "260003" + }, { + "label": "Motor Home and Recreational Vehicle Rental", + "mccCode": "260004" + }, { + "label": "Truck Rental", + "mccCode": "260005" + }] +}, { + "label": "Repair Services", + "children": [{ + "label": "Air Conditioning and Refrigeration Repair Shops", + "mccCode": "270001" + }, { + "label": "Automotive Body Repair Shops", + "mccCode": "270002" + }, { + "label": "Automotive Paint Shops", + "mccCode": "270003" + }, { + "label": "Automotive Service Shops", + "mccCode": "270004" + }, { + "label": "Clock, Jewelry and Watch Repair Shops", + "mccCode": "270005" + }, { + "label": "Electrical and Small Appliance Repair Shops", + "mccCode": "270006" + }, { + "label": "Electronic Repair Shops", + "mccCode": "270007" + }, { + "label": "Furniture-Reupholstery and Repair, Refinishing", + "mccCode": "270008" + }, { + "label": "Miscellaneous Repair Shops and Related Services", + "mccCode": "270009" + }, { + "label": "Tire Retreading and Repair Shops", + "mccCode": "270010" + }, { + "label": "Towing Services", + "mccCode": "270011" + }, { + "label": "Welding Repair", + "mccCode": "270012" + }] +}, { + "label": "Retail", + "children": [{ + "label": "Antique Reproduction Stores", + "mccCode": "280001" + }, { + "label": "Antique Shops-Sales, Repairs, Restoration Services", + "mccCode": "280002" + }, { + "label": "Art Dealers and Galleries", + "mccCode": "280003" + }, { + "label": "Artist Supply Stores, Craft Shops", + "mccCode": "280004" + }, { + "label": "Bakeries", + "mccCode": "280005" + }, { + "label": "Bicycle Shops-Sales and Service", + "mccCode": "280006" + }, { + "label": "Book Stores", + "mccCode": "280007" + }, { + "label": "Books, Periodicals and Newspapers", + "mccCode": "280008" + }, { + "label": "Building Materials, Lumber Stores", + "mccCode": "280009" + }, { + "label": "Camera and Photographic Supply Stores", + "mccCode": "280010" + }, { + "label": "Candy, Nut, Confectionery Stores", + "mccCode": "280011" + }, { + "label": "Chemicals/Allied Products-Not Elsewhere Classified", + "mccCode": "280012" + }, { + "label": "Clock, Jewelry, Watch and Silverware Store", + "mccCode": "280013" + }, { + "label": "Commercial Footwear", + "mccCode": "280014" + }, { + "label": "Computers, Computer Peripheral Equipment, Software", + "mccCode": "280015" + }, { + "label": "Construction Materials-Not Elsewhere Classified", + "mccCode": "280016" + }, { + "label": "Cosmetic Stores", + "mccCode": "280017" + }, { + "label": "Crystal and Glassware Stores", + "mccCode": "280018" + }, { + "label": "Dairy Products Stores", + "mccCode": "280019" + }, { + "label": "Dental/Lab/Med/Ophthalmic Hosp Equip & Supplies", + "mccCode": "280020" + }, { + "label": "Department Stores", + "mccCode": "280021" + }, { + "label": "Discount Stores", + "mccCode": "280022" + }, { + "label": "Drapery, Upolstery and Window Coverings Stores", + "mccCode": "280023" + }, { + "label": "Duty Free Stores", + "mccCode": "280024" + }, { + "label": "Electric Razor Stores-Sales and Service", + "mccCode": "280025" + }, { + "label": "Electrical Parts and Equipment", + "mccCode": "280026" + }, { + "label": "Fabric, Needlework, Piece Goods and Sewing Stores", + "mccCode": "280027" + }, { + "label": "Fireplace, Fireplace Screens & Accessories Stores", + "mccCode": "280028" + }, { + "label": "Floor Covering Stores", + "mccCode": "280029" + }, { + "label": "Florist Supplies, Nursery Stock & Flowers", + "mccCode": "280030" + }, { + "label": "Florists", + "mccCode": "280031" + }, { + "label": "Freezer, Locker Meat Provisioners", + "mccCode": "280032" + }, { + "label": "Furniture, Home Furnshngs", + "mccCode": "280033" + }, { + "label": "Game, Toy and Hobby Shops", + "mccCode": "280034" + }, { + "label": "Gift, Card, Novelty and Souvenir Shops", + "mccCode": "280035" + }, { + "label": "Glass, Paint, Wallpaper Stores", + "mccCode": "280036" + }, { + "label": "Grocery Stores, Supermarkets", + "mccCode": "280037" + }, { + "label": "Hardware Equipment and Supplies", + "mccCode": "280038" + }, { + "label": "Hardware Stores", + "mccCode": "280039" + }, { + "label": "Home Supply Warehouse Stores", + "mccCode": "280040" + }, { + "label": "Household Appliance Stores", + "mccCode": "280041" + }, { + "label": "Industrial Supplies-Not Elsewhere Classified", + "mccCode": "280042" + }, { + "label": "Lawn and Garden Supply Stores", + "mccCode": "280043" + }, { + "label": "Leather Goods and Luggage Stores", + "mccCode": "280044" + }, { + "label": "Men's/Women's/Children's Uniforms/Commercial Cloth", + "mccCode": "280045" + }, { + "label": "Metal Service Centers and Offices", + "mccCode": "280046" + }, { + "label": "Misc Food Store-Convenience, Mrkt, Splty, Vendng Macs", + "mccCode": "280047" + }, { + "label": "Miscellaneous and Specialty Retail Stores", + "mccCode": "280048" + }, { + "label": "Miscellaneous General Merchandise", + "mccCode": "280049" + }, { + "label": "Miscellaneous House Furnishing Specialty Shops", + "mccCode": "280050" + }, { + "label": "Mobile Home Dealers", + "mccCode": "280051" + }, { + "label": "Motor Vehicle Supplies and New Parts", + "mccCode": "280052" + }, { + "label": "Music Stores-Instruments, Pianos, Sheet Music", + "mccCode": "280053" + }, { + "label": "News Dealers and Newsstands", + "mccCode": "280054" + }, { + "label": "Nondurable Goods-Not Elsewhere Classified", + "mccCode": "280055" + }, { + "label": "Office and Commercial Furniture", + "mccCode": "280056" + }, { + "label": "Office Photographic Photocopy & Microfilm Equipmt.", + "mccCode": "280057" + }, { + "label": "Office, School Supply and Stationery Stores", + "mccCode": "280058" + }, { + "label": "Package Stores, Beer, Wine, Liquor", + "mccCode": "280059" + }, { + "label": "Paints, Varnishes and Supplies", + "mccCode": "280060" + }, { + "label": "Pawn Shops", + "mccCode": "280061" + }, { + "label": "Pet Shops-Pet Foods and Supplies", + "mccCode": "280062" + }, { + "label": "Petroleum and Petroleum Products", + "mccCode": "280063" + }, { + "label": "Piece Goods, Notions and Other Dry Goods", + "mccCode": "280064" + }, { + "label": "Plumbing and Heating Equipment", + "mccCode": "280065" + }, { + "label": "Precious Stones and Metals, Watches and Jewelry", + "mccCode": "280066" + }, { + "label": "Record Shops", + "mccCode": "280067" + }, { + "label": "Second Hand Stores, Used Merchandise Stores", + "mccCode": "280068" + }, { + "label": "Sporting Goods Stores", + "mccCode": "280069" + }, { + "label": "Stationery/Office Supplies/Printing & Writing Pap", + "mccCode": "280070" + }, { + "label": "Swimming Pools-Sales and Supplies", + "mccCode": "280071" + }, { + "label": "Tent and Awning Shops", + "mccCode": "280072" + }, { + "label": "Typewriter Stores-Rentals, Sales, Service", + "mccCode": "280073" + }, { + "label": "Variety Stores", + "mccCode": "280074" + }, { + "label": "Video Entertainment Rental Stores", + "mccCode": "280075" + }] +}, { + "label": "Retail Clothing & Fashion", + "children": [{ + "label": "Accessory and Apparel Stores-Miscellaneous", + "mccCode": "290001" + }, { + "label": "Alterations, Mending, Seamstresses, Tailors", + "mccCode": "290002" + }, { + "label": "Children's and Infant's Wear Stores", + "mccCode": "290003" + }, { + "label": "Clothing Rental-Costumes, Uniforms, Formal Wear", + "mccCode": "290004" + }, { + "label": "Family Clothing Stores", + "mccCode": "290005" + }, { + "label": "Furriers and Fur Shops", + "mccCode": "290006" + }, { + "label": "Men's and Boy's Clothing and Accessories Stores", + "mccCode": "290007" + }, { + "label": "Men's and Women's Clothing Stores", + "mccCode": "290008" + }, { + "label": "Shoe Stores", + "mccCode": "290009" + }, { + "label": "Sports Apparel, Riding Apparel Stores", + "mccCode": "290010" + }, { + "label": "Wig and Toupee Shops", + "mccCode": "290011" + }, { + "label": "Women's Accessory and Specialty Stores", + "mccCode": "290012" + }, { + "label": "Women's Ready To Wear Stores", + "mccCode": "290013" + }] +}, { + "label": "Sales", + "children": [{ + "label": "Direct Marketing-Catalog Merchants", + "mccCode": "310001" + }, { + "label": "Direct Marketing-Combination Catalog/Retail Merch", + "mccCode": "310002" + }, { + "label": "Direct Marketing-Continuity/Subscription Merchants", + "mccCode": "310003" + }, { + "label": "Direct Marketing-Inbound Telemarketing Merchants", + "mccCode": "310004" + }, { + "label": "Direct Marketing-Insurance Services", + "mccCode": "310005" + }, { + "label": "Direct Marketing-Other Direct Marketers/Not Elsew", + "mccCode": "310006" + }, { + "label": "Direct Marketing-Outbound Telemarketing Merchants", + "mccCode": "310007" + }, { + "label": "Direct Marketing-Travel Related Arrangement Servs", + "mccCode": "310008" + }, { + "label": "Door-To-Door Sales", + "mccCode": "310009" + }] +}, { + "label": "Sports & Games", + "children": [{ + "label": "Athltic Fields, Commrcl Sprt, Sprt Clbs, Sprt Promotr", + "mccCode": "320001" + }, { + "label": "Bicycle Shops-Sales and Service", + "mccCode": "320002" + }, { + "label": "Bowling Alleys", + "mccCode": "320003" + }, { + "label": "Golf Courses-Public", + "mccCode": "320004" + }, { + "label": "Sporting Goods Stores", + "mccCode": "320005" + }, { + "label": "Sports Apparel, Riding Apparel Stores", + "mccCode": "320006" + }] +}, { + "label": "Storage", + "children": [{ + "label": "Public Warehousing-Farm, Refrig Goods, Hhg Storage", + "mccCode": "330001" + }] +}, { + "label": "Trade Services", + "children": [{ + "label": "Air Conditioning and Refrigeration Repair Shops", + "mccCode": "340001" + }, { + "label": "Automotive Body Repair Shops", + "mccCode": "340002" + }, { + "label": "Automotive Paint Shops", + "mccCode": "340003" + }, { + "label": "Building Materials, Lumber Stores", + "mccCode": "340004" + }, { + "label": "Carpentry Contractors", + "mccCode": "340005" + }, { + "label": "Concrete Work Contractors", + "mccCode": "340006" + }, { + "label": "Contractors, Special Trade-Not Elsewhere Classified", + "mccCode": "340007" + }, { + "label": "Electrical Contractors", + "mccCode": "340008" + }, { + "label": "Exterminating and Disinfecting Services", + "mccCode": "340009" + }, { + "label": "General Contractors/Residential Buildings", + "mccCode": "340010" + }, { + "label": "Glass, Paint, Wallpaper Stores", + "mccCode": "340011" + }, { + "label": "Hardware Stores", + "mccCode": "340012" + }, { + "label": "Heating, Plumbing, Air Conditioning Contractors", + "mccCode": "340013" + }, { + "label": "Industrial Supplies-Not Elsewhere Classified", + "mccCode": "340014" + }, { + "label": "Insulation, Masonry, Plster, Stonewrk, Tileset Cntrctr", + "mccCode": "340015" + }, { + "label": "Landscaping and Horticultural Services", + "mccCode": "340016" + }, { + "label": "Lawn and Garden Supply Stores", + "mccCode": "340017" + }, { + "label": "Plumbing and Heating Equipment", + "mccCode": "340018" + }, { + "label": "Roofing and Siding, Sheet Metal Work Contractors", + "mccCode": "340019" + }, { + "label": "Sanitation, Polishing & Speciality Cleaning Prep", + "mccCode": "340021" + }, { + "label": "Swimming Pools - Sales and Supplies", + "mccCode": "340022" + }, { + "label": "Swimming Pools-Sales and Supplies", + "mccCode": "340023" + }, { + "label": "Tire Retreading and Repair Shops", + "mccCode": "340024" + }, { + "label": "Towing Services", + "mccCode": "340025" + }, { + "label": "Typesetting, Plate Making & Related Services", + "mccCode": "340026" + }, { + "label": "Welding Repair", + "mccCode": "340027" + }] +}, { + "label": "Utilities", + "children": [{ + "label": "Cable, Satellite, Other Pay Television, Radio Svcs", + "mccCode": "350001" + }, { + "label": "Computer Network/Information Services", + "mccCode": "350002" + }, { + "label": "Money Transfer", + "mccCode": "350003" + }, { + "label": "Telecom Incl Prepaid/Recurring Phone Svcs", + "mccCode": "350004" + }, { + "label": "Telecommunication Equipment Incl Telephone Sales", + "mccCode": "350005" + }, { + "label": "Telegraph Services", + "mccCode": "350006" + }, { + "label": "Utlts-Elctrc, Gas, Heating Oil, Sanitary, Water", + "mccCode": "350007" + }] +}, { + "label": "Vets/Animal Services", + "children": [{ + "label": "Pet Shops-Pet Foods and Supplies", + "mccCode": "360001" + }, { + "label": "Veterinary Services", + "mccCode": "360002" + }] +}, { + "label": "Wholesale", + "children": [{ + "label": "Commercial Equipment-Not Elsewhere Classified", + "mccCode": "370001" + }, { + "label": "Durable Goods-Not Elsewhere Classified", + "mccCode": "370002" + }, { + "label": "Wholesale Clubs", + "mccCode": "370003" + }] +}] diff --git a/src/main/ui/static/images/royalpay_newsletter_thank_you.png b/src/main/ui/static/images/royalpay_newsletter_thank_you.png new file mode 100644 index 000000000..433c952f7 Binary files /dev/null and b/src/main/ui/static/images/royalpay_newsletter_thank_you.png differ diff --git a/src/main/ui/static/images/royalpay_newsletter_thank_you_en.png b/src/main/ui/static/images/royalpay_newsletter_thank_you_en.png new file mode 100644 index 000000000..a432d0e21 Binary files /dev/null and b/src/main/ui/static/images/royalpay_newsletter_thank_you_en.png differ diff --git a/src/main/ui/static/payment/partner/templates/partner_application_detail.html b/src/main/ui/static/payment/partner/templates/partner_application_detail.html index 2dbbe5252..c4b48361a 100644 --- a/src/main/ui/static/payment/partner/templates/partner_application_detail.html +++ b/src/main/ui/static/payment/partner/templates/partner_application_detail.html @@ -175,6 +175,21 @@

+
+ + +
+

+
+
+
+ + +
+

+
+
+ @@ -238,4 +253,4 @@ - \ No newline at end of file + diff --git a/src/test/java/au/com/royalpay/payment/manage/valid/QCloudSignTest.java b/src/test/java/au/com/royalpay/payment/manage/valid/QCloudSignTest.java new file mode 100644 index 000000000..e10e6aac4 --- /dev/null +++ b/src/test/java/au/com/royalpay/payment/manage/valid/QCloudSignTest.java @@ -0,0 +1,81 @@ +package au.com.royalpay.payment.manage.valid; + +import au.com.royalpay.payment.manage.support.serverless.qcloud.support.ServerLessFunctionInvokeRequest; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import org.apache.commons.lang3.RandomUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.net.util.Base64; +import org.junit.Test; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.http.ResponseEntity; +import org.springframework.http.converter.StringHttpMessageConverter; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; + +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import java.nio.charset.StandardCharsets; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; + +/** + * Create by davep at 2019-08-08 16:21 + */ +public class QCloudSignTest { + + private String function = "export_merchants"; + private String region = "ap-hongkong"; + private String secretId = "AKIDlHdjgWzZliPvBauZFfrnW0MaZOyHdTPz"; + private String secretKey = "YswoQDsIZfWEqEAEvMXS8Yic84lFn9Jp"; + + @Test + public void printUrl() throws NoSuchAlgorithmException, InvalidKeyException { + String host = "scf.tencentcloudapi.com/"; + String method = "GET"; + Map paramsMap = new HashMap<>(); + paramsMap.put("Action", "Invoke"); + paramsMap.put("Version", "2018-04-16"); + paramsMap.put("Region", region); + paramsMap.put("FunctionName", function); + paramsMap.put("ClientContext", "{\"client_moniker\":\"PINE\"}"); + paramsMap.put("Nonce", "" + RandomUtils.nextInt(0, 999999)); + paramsMap.put("Timestamp", "" + System.currentTimeMillis() / 1000); + paramsMap.put("SignatureMethod", "HmacSHA256"); + paramsMap.put("SecretId", secretId); + + String[] params = paramsMap.entrySet().stream().map(entry -> entry.getKey() + "=" + entry.getValue()).toArray(String[]::new); + + Arrays.sort(params); + String base = method + host + "?" + StringUtils.join(params, "&"); + String key = secretKey; + + Mac sha256HMAC = Mac.getInstance("HmacSHA256"); + SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "HmacSHA256"); + sha256HMAC.init(secretKey); + byte[] finalBytes = sha256HMAC.doFinal(base.getBytes()); + String sign = Base64.encodeBase64String(finalBytes); + paramsMap.put("Signature", sign); + UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl("https://" + host); + for (Map.Entry entry : paramsMap.entrySet()) { + builder.queryParam(entry.getKey(), entry.getValue()); + } + System.out.println(builder.build(false).encode().toUriString()); + } + + @Test + public void v3Test() { + RestTemplate restTemplate = new RestTemplateBuilder() + .messageConverters(new StringHttpMessageConverter(StandardCharsets.UTF_8)) + .build(); + JSONObject params = new JSONObject(); + params.put("client_moniker", "PINE"); + ServerLessFunctionInvokeRequest request = new ServerLessFunctionInvokeRequest(secretId, secretKey, region, function, params); + ResponseEntity resp = restTemplate.exchange(request.request(), String.class); + System.out.println(resp.getBody()); + + } +}