diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/lakala/LklLedgerMember.java b/mall-common/src/main/java/com/suisung/mall/common/modules/lakala/LklLedgerMember.java new file mode 100644 index 00000000..fd096b1f --- /dev/null +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/lakala/LklLedgerMember.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. + * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. + * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. + * Vestibulum commodo. Ut rhoncus gravida arcu. + */ + +package com.suisung.mall.common.modules.lakala; + +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.Date; + +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("shop_message_template") +@ApiModel(value = "拉卡拉分账商户", description = "拉卡拉分账商户表") +public class LklLedgerMember implements Serializable { + private static final long serialVersionUID = 1L; + + private Long id; + private String order_no; + private String org_code; + private String mer_inner_no; + private String mer_cup_no; + private String contact_mobile; + private String split_lowest_ratio; + private String split_entrust_file_name; + private String split_entrust_file_path; + private String split_range; + private String sep_fund_source; + private String ele_contract_no; + private String split_launch_mode; + private String settle_type; + private String split_rule_source; + private String ret_url; + private String apply_id; + private String audit_status; + private String audit_status_text; + private String remark; + private String version; + private Date created_at; + private Date updated_at; +} diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/lakala/LklLedgerMerReceiverBind.java b/mall-common/src/main/java/com/suisung/mall/common/modules/lakala/LklLedgerMerReceiverBind.java new file mode 100644 index 00000000..d1419ecb --- /dev/null +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/lakala/LklLedgerMerReceiverBind.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. + * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. + * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. + * Vestibulum commodo. Ut rhoncus gravida arcu. + */ + +package com.suisung.mall.common.modules.lakala; + +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.Date; + +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("shop_message_template") +@ApiModel(value = "拉卡拉分账商户与接收方绑定关系", description = "拉卡拉分账商户与接收方绑定表") +public class LklLedgerMerReceiverBind implements Serializable { + private static final long serialVersionUID = 1L; + + private Long id; + private String order_no; + private String org_code; + private String mer_inner_no; + private String mer_cup_no; + private String receiver_no; + private String entrust_file_name; + private String entrust_file_path; + private String ret_url; + private String apply_id; + private String audit_status; + private String audit_status_text; + private String remark; + private String version; + private Date created_at; + private Date updated_at; +} diff --git a/mall-common/src/main/java/com/suisung/mall/common/modules/lakala/LklLedgerReceiver.java b/mall-common/src/main/java/com/suisung/mall/common/modules/lakala/LklLedgerReceiver.java new file mode 100644 index 00000000..d3fedb3c --- /dev/null +++ b/mall-common/src/main/java/com/suisung/mall/common/modules/lakala/LklLedgerReceiver.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. + * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. + * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. + * Vestibulum commodo. Ut rhoncus gravida arcu. + */ + +package com.suisung.mall.common.modules.lakala; + +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.Date; + +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("shop_message_template") +@ApiModel(value = "拉卡拉分账接收方", description = "拉卡拉分账接收方表") +public class LklLedgerReceiver implements Serializable { + private static final long serialVersionUID = 1L; + + private Long id; + private String order_no; + private String org_code; + private String rec_org_code; + private String rec_org_name; + private String receiver_name; + private String contact_mobile; + private String license_no; + private String license_name; + private String legal_person_name; + private String legal_person_certificate_type; + private String legal_person_certificate_no; + private String acct_no; + private String acct_name; + private String acct_type_code; + private String acct_certificate_type; + private String acct_certificate_no; + private String acct_open_bank_code; + private String acct_open_bank_name; + private String acct_clear_bank_code; + private String attach_list; + private String attach_type; + private String attach_name; + private String attach_store_path; + private String settle_type; + private String version; + private Date created_at; + private Date updated_at; +} diff --git a/mall-common/src/main/java/com/suisung/mall/common/utils/StringUtils.java b/mall-common/src/main/java/com/suisung/mall/common/utils/StringUtils.java index baae74b8..3a1dcb52 100644 --- a/mall-common/src/main/java/com/suisung/mall/common/utils/StringUtils.java +++ b/mall-common/src/main/java/com/suisung/mall/common/utils/StringUtils.java @@ -16,6 +16,7 @@ import java.security.SecureRandom; import java.text.MessageFormat; import java.text.SimpleDateFormat; import java.util.*; +import java.util.concurrent.ThreadLocalRandom; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -73,6 +74,35 @@ public final class StringUtils extends org.apache.commons.lang3.StringUtils { return key; } + /** + * 生成拉卡拉的订单号 + * 规则:14位年月日时(24小时制)分秒+8位的随机数(不重复)如:2021020112000012345678 + * + * @param randomLen + * @return + */ + public static String genLklOrderNo(int randomLen) { + SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss", Locale.getDefault()); + return format.format(new Date()) + genRandomNumber(randomLen); + } + + public static String genRandomNumber(int n) { + if (n <= 0) { + return ""; + } + + StringBuilder sb = new StringBuilder(); + // 生成首位,范围是 1 - 9,确保随机数是 n 位而不是 n - 1 位 + sb.append(ThreadLocalRandom.current().nextInt(1, 10)); + + for (int i = 1; i < n; i++) { + // 生成后续位,范围是 0 - 9 + sb.append(ThreadLocalRandom.current().nextInt(0, 10)); + } + + return sb.toString(); + } + /** * 字符串格式化 *

@@ -323,6 +353,60 @@ public final class StringUtils extends org.apache.commons.lang3.StringUtils { } } + /** + * 驼峰命名转下划线命名 + * + * @param camelCase 驼峰命名的字符串 + * @return 下划线命名的字符串 + */ + public static String camelToSnake(String camelCase) { + // 处理输入为 null 或空字符串的情况 + if (camelCase == null || camelCase.isEmpty()) { + return camelCase; + } + StringBuilder result = new StringBuilder(); + for (int i = 0; i < camelCase.length(); i++) { + char c = camelCase.charAt(i); + // 如果是大写字母且不是字符串的第一个字符,则在前面添加下划线 + if (Character.isUpperCase(c) && i > 0) { + result.append("_"); + } + // 将字符转换为小写并添加到结果中 + result.append(Character.toLowerCase(c)); + } + return result.toString(); + } + + /** + * 下划线命名转驼峰命名 + * + * @param snakeCase 下划线命名的字符串 + * @return 驼峰命名的字符串 + */ + public static String snakeToCamel(String snakeCase) { + // 处理输入为 null 或空字符串的情况 + if (snakeCase == null || snakeCase.isEmpty()) { + return snakeCase; + } + StringBuilder result = new StringBuilder(); + boolean capitalizeNext = false; + for (char c : snakeCase.toCharArray()) { + if (c == '_') { + // 遇到下划线,标记下一个字符要大写 + capitalizeNext = true; + } else { + if (capitalizeNext) { + // 将字符转换为大写并添加到结果中 + result.append(Character.toUpperCase(c)); + capitalizeNext = false; + } else { + result.append(c); + } + } + } + return result.toString(); + } + /** * 生成的随机数类型 diff --git a/mall-pay/src/main/java/com/suisung/mall/pay/controller/mobile/IndexController.java b/mall-pay/src/main/java/com/suisung/mall/pay/controller/mobile/IndexController.java index d4f2b3e6..1b2287be 100644 --- a/mall-pay/src/main/java/com/suisung/mall/pay/controller/mobile/IndexController.java +++ b/mall-pay/src/main/java/com/suisung/mall/pay/controller/mobile/IndexController.java @@ -58,13 +58,13 @@ public class IndexController extends BaseControllerImpl { @Autowired private PayUserResourceService payUserResourceService; @Autowired - private LakalaService lakalaService; + private LakalaPayService lakalaPayService; @ApiOperation(value = "测试接口", notes = "测试接口") @RequestMapping(value = "/test/case", method = RequestMethod.POST) public JSONObject testCase(HttpServletRequest request, HttpServletResponse response, @RequestBody JSONObject objectJSON){ - return lakalaService.transPreOrder(request,response, (String) objectJSON.get("orderId")); + return lakalaPayService.transPreOrder(request,response, (String) objectJSON.get("orderId")); } @ApiOperation(value = "获取支付密码", notes = "获取支付密码") diff --git a/mall-pay/src/main/java/com/suisung/mall/pay/controller/mobile/LakalaController.java b/mall-pay/src/main/java/com/suisung/mall/pay/controller/mobile/LakalaController.java new file mode 100644 index 00000000..039da04f --- /dev/null +++ b/mall-pay/src/main/java/com/suisung/mall/pay/controller/mobile/LakalaController.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. + * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. + * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. + * Vestibulum commodo. Ut rhoncus gravida arcu. + */ + +package com.suisung.mall.pay.controller.mobile; + +import cn.hutool.json.JSONObject; +import com.suisung.mall.common.api.CommonResult; +import com.suisung.mall.common.service.impl.BaseControllerImpl; +import com.suisung.mall.pay.service.LakalaPayService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +@Api(tags = "拉卡拉相关接口 - 前端控制器") +@RestController +@RequestMapping("/mobile/pay/lakala") +public class LakalaController extends BaseControllerImpl { + + @Autowired + private LakalaPayService lakalaPayService; + + @ApiOperation(value = "商户分账业务开通申请", notes = "商户分账业务开通申请") + @RequestMapping(value = "/ledger/applyLedgerMer", method = RequestMethod.POST) + public CommonResult ledgerApplyLedgerMer(@RequestBody JSONObject paramsJSON) { + return lakalaPayService.ledgerApplyLedgerMer(paramsJSON); + } + + @ApiOperation(value = "商户分账业务开通申请异步回调回调", notes = "商户分账业务开通申请异步回调回调") + @RequestMapping(value = "/ledger/applyLedgerMerNotify", method = RequestMethod.POST) + public CommonResult ledgerApplyLedgerMerNotify(@RequestBody JSONObject paramsJSON) { + return lakalaPayService.ledgerApplyLedgerMer(paramsJSON); + } + + @ApiOperation(value = "分账接收方创建申请", notes = "分账接收方创建申请") + @RequestMapping(value = "/ledger/applyLedgerReceiver", method = RequestMethod.POST) + public CommonResult applyLedgerReceiver(@RequestBody JSONObject paramsJSON) { + return lakalaPayService.ledgerApplyLedgerMer(paramsJSON); + } + + @ApiOperation(value = "分账关系绑定申请", notes = "分账关系绑定申请") + @RequestMapping(value = "/ledger/applyBind", method = RequestMethod.POST) + public CommonResult applyBind(@RequestBody JSONObject paramsJSON) { + return lakalaPayService.ledgerApplyLedgerMer(paramsJSON); + } + + @ApiOperation(value = "分账关系绑定申请异步回调通知", notes = "分账关系绑定申请异步回调通知") + @RequestMapping(value = "/ledger/applyBindNotify", method = RequestMethod.POST) + public CommonResult applyBindNotify(@RequestBody JSONObject paramsJSON) { + return lakalaPayService.ledgerApplyLedgerMer(paramsJSON); + } + + +} diff --git a/mall-pay/src/main/java/com/suisung/mall/pay/mapper/LklLedgerMemberMapper.java b/mall-pay/src/main/java/com/suisung/mall/pay/mapper/LklLedgerMemberMapper.java new file mode 100644 index 00000000..149d5a70 --- /dev/null +++ b/mall-pay/src/main/java/com/suisung/mall/pay/mapper/LklLedgerMemberMapper.java @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. + * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. + * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. + * Vestibulum commodo. Ut rhoncus gravida arcu. + */ + +package com.suisung.mall.pay.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.suisung.mall.common.modules.lakala.LklLedgerMember; +import com.suisung.mall.common.modules.pay.PayBaseRechargeLevel; +import org.springframework.stereotype.Repository; + + +@Repository +public interface LklLedgerMemberMapper extends BaseMapper { +} diff --git a/mall-pay/src/main/java/com/suisung/mall/pay/service/LakalaPayService.java b/mall-pay/src/main/java/com/suisung/mall/pay/service/LakalaPayService.java new file mode 100644 index 00000000..420ee481 --- /dev/null +++ b/mall-pay/src/main/java/com/suisung/mall/pay/service/LakalaPayService.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. + * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. + * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. + * Vestibulum commodo. Ut rhoncus gravida arcu. + */ + +package com.suisung.mall.pay.service; + +import cn.hutool.json.JSONObject; +import com.suisung.mall.common.api.CommonResult; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public interface LakalaPayService { + + Boolean initLKLSDK(); + + JSONObject transPreOrder(HttpServletRequest request, HttpServletResponse response, String orderId); + + /** + * 拉卡拉预下单 + * 参考:https://o.lakala.com/#/home/document/detail?id=110 + * + * @param merchantNo 商户号 + * @param termNo 终端号 + * @param xcxAppId 小程序appid + * @param openId openid + * @param orderId 订单号 + * @param subject 订单标题 + * @param totalAmount 订单金额 + * @param notifyURL 回调地址 + * @param requestIP 请求ip + * @param remark 备注 + * @return + */ + JSONObject transPreOrder(String merchantNo, String termNo, String xcxAppId, String openId, String orderId, String subject, String totalAmount, String notifyURL, String requestIP, String remark); + + /** + * 聚合扫码-交易查询 + * + * @param storeId + * @param orderId + * @return + */ + JSONObject tradeQuery(Integer storeId, String orderId); + + /** + * 聚合扫码-退款交易 + * 主被扫交易发生后,因商家或消费者原因需要退款时,商家调用此接口退还消费者支付款项。 + * 注意: 1、调用退款接口时请保证商户/账户余额大于等于本次退款金额 + * + * @param storeId + * @param out_trade_no + * @param origin_trade_no // 原拉卡拉交易流水号 + * @param refund_amount 单位分,整数数字型字符 + * @param refund_reason + * @param requestIP + * @return + */ + JSONObject refund(Integer storeId, String out_trade_no, String origin_trade_no, String refund_amount, String refund_reason, String requestIP); + + /** + * 账户余额查询 + * 参考:https://o.lakala.com/#/home/document/detail?id=364 + * + * @param orgNo bmcp机构号 + * @param merchantNo 商户号 或 receiveNo 或 商户用户编号 + * @param payNo 账号(若该参数上送,则payType将无效) + * @param payType 账号类型(01:收款账户,02:付款账户,03:分账商户账户,04:分账接收方账户,05:充值代付账户,06:结算代付账户)- 未上送则默认为01 + * @return + */ + JSONObject ewalletBalanceQuery(String orgNo, String merchantNo, String payNo, String payType); + + /** + * 文件上传 + * 参考:https://o.lakala.com/#/home/document/detail?id=90 + * @param orderNo + * @param attType + * @param attExtName + * @param attContext + * @return + */ + JSONObject uploadFile(String orderNo, String attType, String attExtName, String attContext); + + + /** + * 商户分账业务开通申请 + * 参考:https://o.lakala.com/#/home/document/detail?id=379 + * @param paramsJSON + * @return + */ + CommonResult ledgerApplyLedgerMer(JSONObject paramsJSON); +} diff --git a/mall-pay/src/main/java/com/suisung/mall/pay/service/LakalaService.java b/mall-pay/src/main/java/com/suisung/mall/pay/service/LakalaService.java deleted file mode 100644 index 49c39434..00000000 --- a/mall-pay/src/main/java/com/suisung/mall/pay/service/LakalaService.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit. - * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. - * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. - * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. - * Vestibulum commodo. Ut rhoncus gravida arcu. - */ - -package com.suisung.mall.pay.service; - -import cn.hutool.json.JSONObject; -import com.suisung.mall.common.pojo.res.PayAccRespFieldsRes; -import com.wechat.pay.java.service.payments.nativepay.NativePayService; -import org.springframework.data.util.Pair; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -public interface LakalaService { - - Boolean initLKLSDK(); - - JSONObject transPreOrder(HttpServletRequest request, HttpServletResponse response, String orderId); - - /** - * 拉卡拉预下单 - * - * @param merchantNo 商户号 - * @param termNo 终端号 - * @param xcxAppId 小程序appid - * @param openId openid - * @param orderId 订单号 - * @param subject 订单标题 - * @param totalAmount 订单金额 - * @param notifyURL 回调地址 - * @param requestIP 请求ip - * @param remark 备注 - * @return - */ - JSONObject transPreOrder(String merchantNo, String termNo, String xcxAppId, String openId, String orderId, String subject, String totalAmount, String notifyURL, String requestIP, String remark); - - /** - * 拉卡拉查询商户号和终端号 - * - * @param storeId 店铺 id - * @return - */ - Pair getLklMerchantNoAndTermNo(String storeId); -} diff --git a/mall-pay/src/main/java/com/suisung/mall/pay/service/LklLedgerMemberService.java b/mall-pay/src/main/java/com/suisung/mall/pay/service/LklLedgerMemberService.java new file mode 100644 index 00000000..f64fc757 --- /dev/null +++ b/mall-pay/src/main/java/com/suisung/mall/pay/service/LklLedgerMemberService.java @@ -0,0 +1,15 @@ +/* + * Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. + * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. + * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. + * Vestibulum commodo. Ut rhoncus gravida arcu. + */ + +package com.suisung.mall.pay.service; + +import com.suisung.mall.common.modules.lakala.LklLedgerMember; +import com.suisung.mall.core.web.service.IBaseService; + +public interface LklLedgerMemberService extends IBaseService { +} diff --git a/mall-pay/src/main/java/com/suisung/mall/pay/service/impl/LakalaPayServiceImpl.java b/mall-pay/src/main/java/com/suisung/mall/pay/service/impl/LakalaPayServiceImpl.java new file mode 100644 index 00000000..e2b9a043 --- /dev/null +++ b/mall-pay/src/main/java/com/suisung/mall/pay/service/impl/LakalaPayServiceImpl.java @@ -0,0 +1,447 @@ +/* + * Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. + * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. + * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. + * Vestibulum commodo. Ut rhoncus gravida arcu. + */ + +package com.suisung.mall.pay.service.impl; + + +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import com.ijpay.core.kit.IpKit; +import com.lkl.laop.sdk.LKLSDK; +import com.lkl.laop.sdk.exception.SDKException; +import com.lkl.laop.sdk.request.*; +import com.lkl.laop.sdk.request.model.V3LabsTradeLocationInfo; +import com.lkl.laop.sdk.request.model.V3LabsTradePreorderWechatBus; +import com.suisung.mall.common.api.CommonResult; +import com.suisung.mall.common.exception.ApiException; +import com.suisung.mall.common.feignService.ShopService; +import com.suisung.mall.common.modules.lakala.LklLedgerMember; +import com.suisung.mall.common.modules.store.ShopStoreBase; +import com.suisung.mall.common.utils.I18nUtil; +import com.suisung.mall.common.utils.StringUtils; +import com.suisung.mall.pay.service.LakalaPayService; +import com.suisung.mall.pay.service.LklLedgerMemberService; +import com.suisung.mall.pay.utils.LakalaUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.math.BigDecimal; + + +@Slf4j +@Service +public class LakalaPayServiceImpl implements LakalaPayService { + private static final boolean init = false; + //### 可选的两个参数,不同的店铺商家,可以数据库里配置不同的商户号和终端号 + @Value("${lakala.merchant_no}") + public String merchantNo; // 拉卡拉分配的商户号 + @Value("${lakala.term_no}") + public String termNo; // 拉卡拉分配的终端号码 + @Value("${lakala.server_url}") + private String serverUrl; //服务地址 + @Value("${lakala.app_id}") + private String appId; // 拉卡拉appId + @Value("${lakala.serial_no}") + private String serialNo; // 你的证书序列号 + @Value("${lakala.api_pri_key_path}") + private String priKeyPath; //商户私钥信息地址 + @Value("${lakala.lkl_platform_cer_path}") + private String lklCerPath; //拉卡拉支付平台证书地址 + @Value("${lakala.lkl_platform_cer_path}") + private String lklNotifyCerPath; //拉卡拉支付平台证书地址2(用于拉卡拉通知验签) + @Value("${lakala.org_code}") + private String orgCode; + @Value("${project.domain}") + private String projectDomain; + + + @Lazy + @Autowired + private ShopService shopService; + + @Autowired + private LklLedgerMemberService lklLedgerMemberService; + + /** + * 初始化 拉卡拉SDK + * + * @return + */ + @Override + public Boolean initLKLSDK() { + if (!init) { + return LakalaUtil.initLKLSDK(appId, serialNo, priKeyPath, lklCerPath, lklNotifyCerPath, serverUrl); + } + return true; + } + + @Override + public cn.hutool.json.JSONObject transPreOrder(HttpServletRequest request, HttpServletResponse response, String orderId) { + // 1. 配置初始化 + initLKLSDK(); + + //2. 装配数据 + /*** 微信主扫场景示例 */ + V3LabsTransPreorderRequest v3LabsTransPreorderWechatReq = new V3LabsTransPreorderRequest(); + v3LabsTransPreorderWechatReq.setMerchantNo(merchantNo); + v3LabsTransPreorderWechatReq.setTermNo(termNo); + v3LabsTransPreorderWechatReq.setOutTradeNo(orderId); + v3LabsTransPreorderWechatReq.setSubject("油麦菜5斤装特惠"); + v3LabsTransPreorderWechatReq.setAccountType("WECHAT"); + v3LabsTransPreorderWechatReq.setTransType("51"); + v3LabsTransPreorderWechatReq.setTotalAmount("1"); + v3LabsTransPreorderWechatReq.setNotifyUrl("http://mall.gpxscs.cn/notify"); + v3LabsTransPreorderWechatReq.setRemark("测试预下单备注"); + + //地址位置信息 + V3LabsTradeLocationInfo v3LabsTradePreorderLocationInfo1 = new V3LabsTradeLocationInfo(IpKit.getRealIp(request)); + v3LabsTransPreorderWechatReq.setLocationInfo(v3LabsTradePreorderLocationInfo1); + + //微信主扫场景下acc_busi_fields域内容 + V3LabsTradePreorderWechatBus wechatBus = new V3LabsTradePreorderWechatBus(); + wechatBus.setSubAppid("wx5a73f844dac0da5c"); // 小程序appId + wechatBus.setUserId("oDVKR7T0qxg6O8tqIL9SgY6LXqqQ"); // 微信 openId + wechatBus.setDeviceInfo("WEB"); // 终端设备号(门店号或收银设备ID),注意:PC网页或JSAPI支付请传”WEB” + v3LabsTransPreorderWechatReq.setAccBusiFields(wechatBus); + + try { + //3. 发送请求 + String responseStr = LKLSDK.httpPost(v3LabsTransPreorderWechatReq); + + //4. 响应 + return JSONUtil.parseObj(responseStr); + } catch (SDKException e) { + LakalaPayServiceImpl.log.error("transPreOrder error", e); + throw new ApiException(I18nUtil._("获取公众号绑定信息失败!"), e); + } + + } + + /** + * 拉卡拉预下单 + * 参考:https://o.lakala.com/#/home/document/detail?id=110 + * + * @param merchantNo 商户号 + * @param termNo 终端号 + * @param xcxAppId 小程序appid + * @param openId openid + * @param orderId 订单号 + * @param subject 订单标题 + * @param totalAmount 订单金额 + * @param notifyURL 回调地址 + * @param requestIP 请求ip + * @param remark 备注 + * @return + */ + @Override + public JSONObject transPreOrder(String merchantNo, String termNo, String xcxAppId, String openId, String orderId, String subject, String totalAmount, String notifyURL, String requestIP, String remark) { + // 1. 配置初始化 + initLKLSDK(); + + if (StrUtil.isBlank(merchantNo)) { + merchantNo = this.merchantNo; + } + if (StrUtil.isBlank(termNo)) { + termNo = this.termNo; + } + + //2. 装配数据 + /*** 微信主扫场景示例 */ + V3LabsTransPreorderRequest v3LabsTransPreorderWechatReq = new V3LabsTransPreorderRequest(); + v3LabsTransPreorderWechatReq.setMerchantNo(merchantNo); + v3LabsTransPreorderWechatReq.setTermNo(termNo); + v3LabsTransPreorderWechatReq.setOutTradeNo(orderId); + v3LabsTransPreorderWechatReq.setSubject(subject); + //微信:WECHAT 支付宝:ALIPAY 银联:UQRCODEPAY 翼支付: BESTPAY 苏宁易付宝: SUNING 拉卡拉支付账户:LKLACC 网联小钱包:NUCSPAY 京东钱包:JD + v3LabsTransPreorderWechatReq.setAccountType("WECHAT"); + // 41:NATIVE((ALIPAY,云闪付支持,京东白条分期)51:JSAPI(微信公众号支付,支付宝服务窗支付,银联JS支付,翼支付JS支付、拉卡拉钱包支付)71:微信小程序支付 61:APP支付(微信APP支付) + v3LabsTransPreorderWechatReq.setTransType("51"); + v3LabsTransPreorderWechatReq.setTotalAmount(totalAmount); + v3LabsTransPreorderWechatReq.setSettleType("1"); //“0”或者空,常规结算方式,如需接拉卡拉分账通需传“1”,商户未开通分账之前切记不用上送此参数。; + v3LabsTransPreorderWechatReq.setNotifyUrl(notifyURL); + v3LabsTransPreorderWechatReq.setRemark(remark); + + //地址位置信息 + V3LabsTradeLocationInfo v3LabsTradePreorderLocationInfo = new V3LabsTradeLocationInfo(requestIP); + v3LabsTransPreorderWechatReq.setLocationInfo(v3LabsTradePreorderLocationInfo); + + //微信主扫场景下 acc_busi_fields 域内容 + V3LabsTradePreorderWechatBus wechatBus = new V3LabsTradePreorderWechatBus(); + wechatBus.setSubAppid(xcxAppId); // 小程序appId + wechatBus.setUserId(openId); // 微信 openId + wechatBus.setDeviceInfo("WEB"); // 终端设备号(门店号或收银设备ID),注意:PC网页或JSAPI支付请传”WEB” + v3LabsTransPreorderWechatReq.setAccBusiFields(wechatBus); + + try { + log.info("拉卡拉预下单请求参数:{}", JSONUtil.toJsonStr(v3LabsTransPreorderWechatReq)); + + //3. 发送请求 + String responseStr = LKLSDK.httpPost(v3LabsTransPreorderWechatReq); + log.info("拉卡拉预下单响应数据:{}", responseStr); + if (StrUtil.isBlank(responseStr)) { + return null; + } + + JSONObject lakalaRespJSON = JSONUtil.parseObj(responseStr); + + // || !lakalaRespJSON.getStr("code").equals("BBS00000") + + //4. 响应 + return lakalaRespJSON; + } catch (SDKException e) { + log.error("拉卡拉支付出错:", e); + throw new ApiException(I18nUtil._("支付失败!"), e); + } + } + + /** + * 聚合扫码-交易查询 + * + * @param storeId + * @param orderId + * @return + */ + @Override + public JSONObject tradeQuery(Integer storeId, String orderId) { + if (ObjectUtil.isEmpty(storeId) || StrUtil.isBlank(orderId)) { + return null; + } + + // 1. 配置初始化 + initLKLSDK(); + + // 这里获取店铺的拉卡拉的商户号和终端号码 + ShopStoreBase shopStoreBase = shopService.getLklMerchantNoAndTermNo(storeId); + if (shopStoreBase == null || StrUtil.isBlank(shopStoreBase.getLkl_merchant_no()) || StrUtil.isBlank(shopStoreBase.getLkl_term_no())) { + log.error("缺少参数,拉卡拉交易查询失败!"); + return null; + } + + //2. 装配数据 + V3LabsQueryTradequeryRequest v3LabsQueryTradequeryRequest = new V3LabsQueryTradequeryRequest(); + v3LabsQueryTradequeryRequest.setMerchantNo(shopStoreBase.getLkl_merchant_no()); + v3LabsQueryTradequeryRequest.setTermNo(shopStoreBase.getLkl_term_no()); + v3LabsQueryTradequeryRequest.setOutTradeNo(orderId); + + try { + //3. 发送请求 + String responseStr = LKLSDK.httpPost(v3LabsQueryTradequeryRequest); + + JSONObject lakalaRespJSON = JSONUtil.parseObj(responseStr); + // || !lakalaRespJSON.getStr("code").equals("BBS00000") + + return lakalaRespJSON; + } catch (SDKException e) { + log.error("交易查询失败:", e); + throw new ApiException(I18nUtil._("交易查询失败!"), e); + } + } + + /** + * 聚合扫码-退款交易 + * 主被扫交易发生后,因商家或消费者原因需要退款时,商家调用此接口退还消费者支付款项。 + * 注意: 1、调用退款接口时请保证商户/账户余额大于等于本次退款金额 + * + * @param storeId + * @param out_trade_no + * @param origin_trade_no // 原拉卡拉交易流水号 + * @param refund_amount 单位分,整数数字型字符 + * @param refund_reason + * @param requestIP + * @return + */ + @Override + public JSONObject refund(Integer storeId, String out_trade_no, String origin_trade_no, String refund_amount, String refund_reason, String requestIP) { + if (ObjectUtil.isEmpty(storeId) || StrUtil.isBlank(out_trade_no) || StrUtil.isBlank(refund_amount) || StrUtil.isBlank(origin_trade_no) || StrUtil.isBlank(requestIP)) { + return null; + } + + // 1. 配置初始化 + initLKLSDK(); + + + // 这里获取店铺的拉卡拉的商户号和终端号码 + ShopStoreBase shopStoreBase = shopService.getLklMerchantNoAndTermNo(storeId); + if (shopStoreBase == null || StrUtil.isBlank(shopStoreBase.getLkl_merchant_no()) || StrUtil.isBlank(shopStoreBase.getLkl_term_no())) { + log.error("缺少参数,退款交易失败!"); + return null; + } + + //2. 装配数据 + V3LabsRelationIdmrefundRequest req = new V3LabsRelationIdmrefundRequest(); + req.setOutRefundOrderNo(out_trade_no); + req.setMerchantNo(shopStoreBase.getLkl_merchant_no()); + req.setTermNo(shopStoreBase.getLkl_term_no()); + req.setRefundAmount(refund_amount); + req.setRefundReason(refund_reason); + req.setOriginTradeNo(origin_trade_no); + + V3LabsTradeLocationInfo v3LabsTradeLocationInfo = new V3LabsTradeLocationInfo(requestIP, null, ""); + req.setLocationInfo(v3LabsTradeLocationInfo); + + try { + //3. 发送请求 + String responseStr = LKLSDK.httpPost(req); + + JSONObject lakalaRespJSON = JSONUtil.parseObj(responseStr); + + return lakalaRespJSON; + } catch (SDKException e) { + log.error("退款交易失败:", e); + throw new ApiException(I18nUtil._("退款交易!"), e); + } + } + + /** + * 账户余额查询 + * 参考:https://o.lakala.com/#/home/document/detail?id=364 + * + * @param orgNo bmcp机构号 测试 “1” + * @param merchantNo 商户号 或 receiveNo 或 商户用户编号 + * @param payNo 账号(若该参数上送,则payType将无效) + * @param payType 账号类型(01:收款账户,02:付款账户,03:分账商户账户,04:分账接收方账户,05:充值代付账户,06:结算代付账户)- 未上送则默认为01 + * @return + */ + @Override + public JSONObject ewalletBalanceQuery(String orgNo, String merchantNo, String payNo, String payType) { + if (StrUtil.isBlank(orgNo) || StrUtil.isBlank(merchantNo) || (StrUtil.isBlank(payNo) && StrUtil.isBlank(payType))) { + return null; + } + + // 1. 配置初始化 + initLKLSDK(); + + + //2. 装配数据 + V2LaepIndustryEwalletBalanceQueryRequest req = new V2LaepIndustryEwalletBalanceQueryRequest(); + req.setOrgNo(orgNo); + req.setMerchantNo(merchantNo); + req.setPayNo(payNo); + req.setPayType(payType); + + try { + //3. 发送请求 + String responseStr = LKLSDK.httpPost(req); + + JSONObject lakalaRespJSON = JSONUtil.parseObj(responseStr); + + return lakalaRespJSON; + } catch (SDKException e) { + log.error("账户余额查询失败:", e); + throw new ApiException(I18nUtil._("账户余额查询!"), e); + } + + } + + /** + * 文件上传 + * 参考:https://o.lakala.com/#/home/document/detail?id=90 + * + * @param orderNo + * @param attType + * @param attExtName + * @param attContext + * @return + */ + @Override + public JSONObject uploadFile(String orderNo, String attType, String attExtName, String attContext) { + // 1. 配置初始化 + initLKLSDK(); + + //2. 装配数据 + V2MmsOpenApiUploadFileRequest req = new V2MmsOpenApiUploadFileRequest(); + req.setVersion("1.0"); + req.setOrderNo(orderNo); + req.setOrgCode(orgCode); + req.setAttType(attType); + req.setAttExtName(attExtName); + req.setAttContext(attContext); + + try { + //3. 发送请求 + String responseStr = LKLSDK.httpPost(req); + + JSONObject lakalaRespJSON = JSONUtil.parseObj(responseStr); + if (lakalaRespJSON == null || !lakalaRespJSON.getStr("retCode").equals("000000") || !lakalaRespJSON.getStr("cmdRetCode").equals("GLOBAL_SUCCESS")) { + throw new ApiException(I18nUtil._(lakalaRespJSON.getStr("retMsg"))); + } + + return (JSONObject) lakalaRespJSON.get("respData"); + } catch (SDKException e) { + log.error("文件上传失败:", e); + throw new ApiException(I18nUtil._("文件上传失败!"), e); + } + } + + @Override + public CommonResult ledgerApplyLedgerMer(JSONObject paramsJSON) { + // 1. 配置初始化 + initLKLSDK(); + + //2. 装配数据 + V2MmsOpenApiLedgerApplyLedgerMerRequest req = new V2MmsOpenApiLedgerApplyLedgerMerRequest(); + req.setVersion("2.0"); + String orderNo = StringUtils.genLklOrderNo(8); + req.setOrderNo(orderNo); + req.setOrgCode(orgCode); + req.setMerInnerNo(paramsJSON.getStr("merInnerNo")); + req.setMerCupNo(paramsJSON.getStr("merCupNo")); + req.setContactMobile(paramsJSON.getStr("contactMobile")); + req.setSplitLowestRatio(new BigDecimal(paramsJSON.getStr("splitLowestRatio"))); + req.setSplitEntrustFileName(paramsJSON.getStr("splitEntrustFileName")); + + + + // 文件上传到拉卡拉服务器 + JSONObject fileUploadResp = uploadFile(orderNo, "SPLIT_ENTRUST_FILE", "png", paramsJSON.getStr("splitEntrustFile")); + if (fileUploadResp != null || StrUtil.isNotBlank(fileUploadResp.getStr("attFileId"))) { + req.setSplitEntrustFilePath(fileUploadResp.getStr("attFileId")); + } +// req.setSplitEntrustFilePath("G1/M00/06/64/CrFdEmBQc-aAGc_XAAAiIbS3WIE960.png"); + + String retUrl = projectDomain + "/mobile/pay/lakala/ledger/applyLedgerMerNotify"; + req.setRetUrl(retUrl); + + paramsJSON.set("orderNo", orderNo); + paramsJSON.set("version", "2.0"); + paramsJSON.set("ret_url", retUrl); + paramsJSON.set("org_code", orgCode); + + try { + + //3. 发送请求 + String responseStr = LKLSDK.httpPost(req); + + JSONObject lakalaRespJSON = JSONUtil.parseObj(responseStr); + if (lakalaRespJSON == null || !lakalaRespJSON.getStr("retCode").equals("000000")) { + throw new ApiException(I18nUtil._(lakalaRespJSON.getStr("retMsg"))); + } + + paramsJSON.set("apply_id", lakalaRespJSON.get("applyId")); + + // 新增数据 + // 将 JSON 对象的键名转换为下划线命名 + LklLedgerMember lklLedgerMember = JSONUtil.toBean(StringUtils.camelToSnake(paramsJSON.toString()), LklLedgerMember.class); + lklLedgerMemberService.edit(lklLedgerMember); + + return CommonResult.success(null, "提交成功,待审核中!"); + } catch (SDKException e) { + log.error("分账申请失败:", e); + throw new ApiException(I18nUtil._("申请失败!"), e); + } + } + + +} diff --git a/mall-pay/src/main/java/com/suisung/mall/pay/service/impl/LakalaServiceImpl.java b/mall-pay/src/main/java/com/suisung/mall/pay/service/impl/LakalaServiceImpl.java deleted file mode 100644 index 2588a808..00000000 --- a/mall-pay/src/main/java/com/suisung/mall/pay/service/impl/LakalaServiceImpl.java +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit. - * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. - * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. - * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. - * Vestibulum commodo. Ut rhoncus gravida arcu. - */ - -package com.suisung.mall.pay.service.impl; - - -import cn.hutool.core.util.StrUtil; -import cn.hutool.json.JSONObject; -import cn.hutool.json.JSONUtil; -import com.ijpay.core.kit.IpKit; -import com.lkl.laop.sdk.LKLSDK; -import com.lkl.laop.sdk.exception.SDKException; -import com.lkl.laop.sdk.request.V3LabsTransPreorderRequest; -import com.lkl.laop.sdk.request.model.V3LabsTradeLocationInfo; -import com.lkl.laop.sdk.request.model.V3LabsTradePreorderWechatBus; -import com.suisung.mall.common.exception.ApiException; -import com.suisung.mall.common.utils.I18nUtil; -import com.suisung.mall.pay.service.LakalaService; -import com.suisung.mall.pay.utils.LakalaUtil; -import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.data.util.Pair; -import org.springframework.stereotype.Service; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - - -@Slf4j -@Service -public class LakalaServiceImpl implements LakalaService { - private static volatile boolean init = false; - - @Value("${lakala.server_url}") - private String serverUrl; //服务地址 - @Value("${lakala.app_id}") - private String appId; // 拉卡拉appId - @Value("${lakala.serial_no}") - private String serialNo; // 你的证书序列号 - @Value("${lakala.api_pri_key_path}") - private String priKeyPath; //商户私钥信息地址 - @Value("${lakala.lkl_platform_cer_path}") - private String lklCerPath; //拉卡拉支付平台证书地址 - @Value("${lakala.lkl_platform_cer_path}") - private String lklNotifyCerPath; //拉卡拉支付平台证书地址2(用于拉卡拉通知验签) - - //### 可选的两个参数,不同的店铺商家,可以数据库里配置不同的商户号和终端号 - @Value("${lakala.merchant_no}") - public String merchantNo; // 拉卡拉分配的商户号 - @Value("${lakala.term_no}") - public String termNo; // 拉卡拉分配的终端号码 - - /** - * 初始化 拉卡拉SDK - * @return - */ - @Override - public Boolean initLKLSDK() { - if (!init) { - return LakalaUtil.initLKLSDK(appId, serialNo, priKeyPath, lklCerPath, lklNotifyCerPath, serverUrl); - } - return true; - } - - @Override - public cn.hutool.json.JSONObject transPreOrder(HttpServletRequest request, HttpServletResponse response, String orderId) { - // 1. 配置初始化 - initLKLSDK(); - - //2. 装配数据 - /*** 微信主扫场景示例 */ - V3LabsTransPreorderRequest v3LabsTransPreorderWechatReq = new V3LabsTransPreorderRequest(); - v3LabsTransPreorderWechatReq.setMerchantNo(merchantNo); - v3LabsTransPreorderWechatReq.setTermNo(termNo); - v3LabsTransPreorderWechatReq.setOutTradeNo(orderId); - v3LabsTransPreorderWechatReq.setSubject("油麦菜5斤装特惠"); - v3LabsTransPreorderWechatReq.setAccountType("WECHAT"); - v3LabsTransPreorderWechatReq.setTransType("51"); - v3LabsTransPreorderWechatReq.setTotalAmount("1"); - v3LabsTransPreorderWechatReq.setNotifyUrl("http://mall.gpxscs.cn/notify"); - v3LabsTransPreorderWechatReq.setRemark("测试预下单备注"); - - //地址位置信息 - V3LabsTradeLocationInfo v3LabsTradePreorderLocationInfo1 = new V3LabsTradeLocationInfo(IpKit.getRealIp(request)); - v3LabsTransPreorderWechatReq.setLocationInfo(v3LabsTradePreorderLocationInfo1); - - //微信主扫场景下acc_busi_fields域内容 - V3LabsTradePreorderWechatBus wechatBus = new V3LabsTradePreorderWechatBus(); - wechatBus.setSubAppid("wx5a73f844dac0da5c"); // 小程序appId - wechatBus.setUserId("oDVKR7T0qxg6O8tqIL9SgY6LXqqQ"); // 微信 openId - wechatBus.setDeviceInfo("WEB"); // 终端设备号(门店号或收银设备ID),注意:PC网页或JSAPI支付请传”WEB” - v3LabsTransPreorderWechatReq.setAccBusiFields(wechatBus); - - try { - //3. 发送请求 - String responseStr = LKLSDK.httpPost(v3LabsTransPreorderWechatReq); - - //4. 响应 - return JSONUtil.parseObj(responseStr); - } catch (SDKException e) { - LakalaServiceImpl.log.error("transPreOrder error", e); - throw new ApiException(I18nUtil._("获取公众号绑定信息失败!"), e); - } - - } - - /** - * 拉卡拉预下单 - * - * @param merchantNo 商户号 - * @param termNo 终端号 - * @param xcxAppId 小程序appid - * @param openId openid - * @param orderId 订单号 - * @param subject 订单标题 - * @param totalAmount 订单金额 - * @param notifyURL 回调地址 - * @param requestIP 请求ip - * @param remark 备注 - * @return - */ - @Override - public JSONObject transPreOrder(String merchantNo, String termNo, String xcxAppId, String openId, String orderId, String subject, String totalAmount, String notifyURL, String requestIP, String remark) { - // 1. 配置初始化 - LakalaUtil.initLKLSDK(appId, serialNo, priKeyPath, lklCerPath, lklNotifyCerPath, serverUrl); - - if (StrUtil.isBlank(merchantNo)) { - merchantNo = this.merchantNo; - } - if (StrUtil.isBlank(termNo)) { - termNo = this.termNo; - } - - //2. 装配数据 - /*** 微信主扫场景示例 */ - V3LabsTransPreorderRequest v3LabsTransPreorderWechatReq = new V3LabsTransPreorderRequest(); - v3LabsTransPreorderWechatReq.setMerchantNo(merchantNo); - v3LabsTransPreorderWechatReq.setTermNo(termNo); - v3LabsTransPreorderWechatReq.setOutTradeNo(orderId); - v3LabsTransPreorderWechatReq.setSubject(subject); - //微信:WECHAT 支付宝:ALIPAY 银联:UQRCODEPAY 翼支付: BESTPAY 苏宁易付宝: SUNING 拉卡拉支付账户:LKLACC 网联小钱包:NUCSPAY 京东钱包:JD - v3LabsTransPreorderWechatReq.setAccountType("WECHAT"); - // 41:NATIVE((ALIPAY,云闪付支持,京东白条分期)51:JSAPI(微信公众号支付,支付宝服务窗支付,银联JS支付,翼支付JS支付、拉卡拉钱包支付)71:微信小程序支付 61:APP支付(微信APP支付) - v3LabsTransPreorderWechatReq.setTransType("51"); - v3LabsTransPreorderWechatReq.setTotalAmount(totalAmount); - v3LabsTransPreorderWechatReq.setSettleType("1"); //“0”或者空,常规结算方式,如需接拉卡拉分账通需传“1”,商户未开通分账之前切记不用上送此参数。; - v3LabsTransPreorderWechatReq.setNotifyUrl(notifyURL); - v3LabsTransPreorderWechatReq.setRemark(remark); - - //地址位置信息 - V3LabsTradeLocationInfo v3LabsTradePreorderLocationInfo = new V3LabsTradeLocationInfo(requestIP); - v3LabsTransPreorderWechatReq.setLocationInfo(v3LabsTradePreorderLocationInfo); - - //微信主扫场景下 acc_busi_fields 域内容 - V3LabsTradePreorderWechatBus wechatBus = new V3LabsTradePreorderWechatBus(); - wechatBus.setSubAppid(xcxAppId); // 小程序appId - wechatBus.setUserId(openId); // 微信 openId - wechatBus.setDeviceInfo("WEB"); // 终端设备号(门店号或收银设备ID),注意:PC网页或JSAPI支付请传”WEB” - v3LabsTransPreorderWechatReq.setAccBusiFields(wechatBus); - - try { - log.info("拉卡拉预下单请求参数:{}", JSONUtil.toJsonStr(v3LabsTransPreorderWechatReq)); - - //3. 发送请求 - String responseStr = LKLSDK.httpPost(v3LabsTransPreorderWechatReq); - log.info("拉卡拉预下单响应数据:{}", responseStr); - if (StrUtil.isBlank(responseStr)) { - return null; - } - - JSONObject res = JSONUtil.parseObj(responseStr); - - //4. 响应 - return res; - } catch (SDKException e) { - log.error("拉卡拉支付出错:", e); - throw new ApiException(I18nUtil._("支付失败!"), e); - } - } - - /** - * 拉卡拉查询商户号和终端号 - * - * @param storeId 店铺 id - * @return - */ - @Override - public Pair getLklMerchantNoAndTermNo(String storeId) { - return Pair.of("",""); - } - - -} diff --git a/mall-pay/src/main/java/com/suisung/mall/pay/service/impl/LklLedgerMemberServiceImpl.java b/mall-pay/src/main/java/com/suisung/mall/pay/service/impl/LklLedgerMemberServiceImpl.java new file mode 100644 index 00000000..5041c01d --- /dev/null +++ b/mall-pay/src/main/java/com/suisung/mall/pay/service/impl/LklLedgerMemberServiceImpl.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025. Lorem ipsum dolor sit amet, consectetur adipiscing elit. + * Morbi non lorem porttitor neque feugiat blandit. Ut vitae ipsum eget quam lacinia accumsan. + * Etiam sed turpis ac ipsum condimentum fringilla. Maecenas magna. + * Proin dapibus sapien vel ante. Aliquam erat volutpat. Pellentesque sagittis ligula eget metus. + * Vestibulum commodo. Ut rhoncus gravida arcu. + */ + +package com.suisung.mall.pay.service.impl; + +import com.suisung.mall.common.modules.lakala.LklLedgerMember; +import com.suisung.mall.common.modules.pay.PayConsumeTrade; +import com.suisung.mall.core.web.service.impl.BaseServiceImpl; +import com.suisung.mall.pay.mapper.LklLedgerMemberMapper; +import com.suisung.mall.pay.mapper.PayConsumeTradeMapper; +import com.suisung.mall.pay.service.LklLedgerMemberService; +import org.springframework.stereotype.Service; + +@Service +public class LklLedgerMemberServiceImpl extends BaseServiceImpl implements LklLedgerMemberService { +} diff --git a/mall-pay/src/main/java/com/suisung/mall/pay/service/impl/PayUserPayServiceImpl.java b/mall-pay/src/main/java/com/suisung/mall/pay/service/impl/PayUserPayServiceImpl.java index d17f919b..0650452f 100644 --- a/mall-pay/src/main/java/com/suisung/mall/pay/service/impl/PayUserPayServiceImpl.java +++ b/mall-pay/src/main/java/com/suisung/mall/pay/service/impl/PayUserPayServiceImpl.java @@ -116,7 +116,7 @@ public class PayUserPayServiceImpl extends BaseServiceImpl params; try { - lakalaService.initLKLSDK(); + lakalaPayService.initLKLSDK(); // spring-boot 2.x 直接调用读取请求体并验签方法,返回请求体 String body = LKLSDK.notificationHandle(request); @@ -1296,19 +1296,15 @@ public class PayUserPayServiceImpl extends BaseServiceImpl tradeQueryWrapper = new QueryWrapper<>(); tradeQueryWrapper.eq("order_id", order_id); PayConsumeTrade trade_row_tmp = payConsumeTradeService.findOne(tradeQueryWrapper); - if (trade_row_tmp != null) { payment_store_id = trade_row_tmp.getStore_id(); orderSubject = trade_row_tmp.getTrade_title(); userId = trade_row_tmp.getBuyer_id(); } - //} QueryWrapper channelQueryWrapper = new QueryWrapper<>(); channelQueryWrapper.eq("payment_channel_code", "lakala"); @@ -1324,8 +1320,8 @@ public class PayUserPayServiceImpl extends BaseServiceImpl114.132.210.208 D:/wwwroot/mall/public/static + + https://mall.gpxscs.cn false @@ -390,6 +392,8 @@ 114.132.210.208 D:/wwwroot/mall/public/static + + https://mall.gpxscs.cn false @@ -437,6 +441,8 @@ 10.1.8.3 /opt/apps/mall/public/static + + https://mall.gpxscs.cn true @@ -484,6 +490,8 @@ 172.16.0.11 /opt/apps/mall/public/static + + https://mall.gpxscs.cn true