首页 > 其他分享 >对接微信分账

对接微信分账

时间:2024-08-29 22:52:26浏览次数:8  
标签:return String 微信 对接 request 分账 public

文章目录

微信分账官方文档

请求分账API - 分账 | 微信支付商户文档中心


微信分账相关参数配置

wx:
  # 微信小程序appid
  app-id: wxcbxxxxxxxxxxxx
  # 商户号
  mch-id: 167xxxxxxx
  # 证书序列号
  mch-serial-no: 7AA998xxxxxxxxxxxxxxxxxxxxxxxxxxx
  # 小程序密钥
  app-secret: 8cc13xxxxxxxxxxxxxxxxxx
  # api密钥
  api-key: toxxxxxxxxxxxxxxxxxxxx
  # 退款通知回调地址
  refund-notify-url: xxx
  # 证书地址
  key-path: /apiclient_key.pem
  cert-path: /apiclient_cert.pem
  cert-p12-path: /apiclient_cert.p12
  msgDataFormat: JSON

相关配置参数获取方法

  • 从这个链接进去获取相关配置

微信支付 - 中国领先的第三方支付平台 | 微信支付提供安全快捷的支付方式


  • 获取APPID

image.png

  • 商户号获取位置

image.png

  • 证书序列号和API秘钥获取位置

image.png

  • 验签相关证书获取位置

image.png
image.png


  • 验签证书直接放在 resources 目录下面

image.png

引入依赖

<!--WeChatPay-->
<dependency>
    <groupId>com.github.wechatpay-apiv3</groupId>
    <artifactId>wechatpay-java</artifactId>
    <version>0.2.12</version>
</dependency>

<!--swagger-->
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-openapi2-spring-boot-starter</artifactId>
    <version>4.1.0</version>
</dependency>

配置类properties

import lombok.Data;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Data
@ToString
@Component
@ConfigurationProperties(prefix = "wx")
public class WxProperties {

    /**
     * 设置微信小程序的appid
     */
    private String appId;

//    /**
//     * 设置微信小程序的Secret
//     */
//    private String appSecret;

    /**
     * 微信支付分配的商户号
     */
    private String mchId;

    /**
     * 密钥文件的路径
     */
    private String keyPath;

    /**
     * 商户证书的路径
     */
    private String certPath;

    /**
     * 商户密钥,用于签名和验证
     */
    private String apiKey;

    /**
     * 退款回调地址
     */
    private String refundNotifyUrl;

    /**
     * 商户API证书序列号
     */
    private String mchSerialNo;

    /**
     * 消息格式,XML或者JSON
     */
    private String msgDataFormat;


}


配置类config

import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.service.profitsharing.ProfitsharingService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.cert.*;

/**
 * 微信支付相关自动配置
 * @author Ccoo
 * 2024/3/24
 */
@Slf4j
@Configuration
public class WechatAutoConfiguration {

	@Autowired
	private WxProperties wxProperties;
	@Autowired
	private ResourceLoader resourceLoader;
	private static final String CLASS_PATH = "classpath:";

	/**
	 * 微信支付分账
	 * @param config Config
	 * @return ProfitsharingService
	 */
	@Bean
	public ProfitsharingService profitsharingService(Config config){
		ProfitsharingService service = new ProfitsharingService.Builder().config(config).build();
		return service;
	}

    /**
	 * 微信支付对象
	 * @param config Config
	 * @return JsapiServiceExtension
	 */
	@Bean
	public JsapiServiceExtension jsapiServiceExtension(Config config){
		JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(config).build();
		return service;
	}
    
	/**
	 * 自动更新证书
	 *
	 * @return RSAAutoCertificateConfig
	 */
	@Bean
	public Config config() throws IOException {
		String path = CLASS_PATH + wxProperties.getCertPath();
		Resource resourceCert = resourceLoader.getResource(path);
		X509Certificate certificate = getCertificate(resourceCert.getInputStream());
		String merchantSerialNumber = certificate.getSerialNumber().toString(16).toUpperCase();

		String privatePath = CLASS_PATH + wxProperties.getKeyPath();
		Resource resourcePrivate = resourceLoader.getResource(privatePath);
		String privateKey = inputStreamToString(resourcePrivate.getInputStream());
		return new RSAAutoCertificateConfig.Builder()
				.merchantId(wxProperties.getMchId())
				.privateKey(privateKey)
				.merchantSerialNumber(merchantSerialNumber)
				.apiV3Key(wxProperties.getApiKey())
				.build();
	}

	/**
	 * 微信回调对象
	 *
	 * @param config Config
	 * @return NotificationParser
	 */
	@Bean
	public NotificationParser notificationParser(Config config) {
		NotificationParser parser = new NotificationParser((NotificationConfig) config);
		return parser;
	}

	/**
	 * 读取私钥文件,将文件流读取成string
	 *
	 * @param inputStream
	 * @return
	 * @throws IOException
	 */
	public String inputStreamToString(InputStream inputStream) throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
		StringBuilder stringBuilder = new StringBuilder();
		String line;
		while ((line = reader.readLine()) != null) {
			stringBuilder.append(line);
		}
		reader.close();
		return stringBuilder.toString();
	}

	/**
	 * 获取证书 将文件流转成证书文件
	 *
	 * @param inputStream 证书文件
	 * @return {@link X509Certificate} 获取证书
	 */
	public static X509Certificate getCertificate(InputStream inputStream) {
		try {
			CertificateFactory cf = CertificateFactory.getInstance("X509");
			X509Certificate cert = (X509Certificate) cf.generateCertificate(inputStream);
			cert.checkValidity();
			return cert;
		} catch (CertificateExpiredException e) {
			throw new RuntimeException("证书已过期", e);
		} catch (CertificateNotYetValidException e) {
			throw new RuntimeException("证书尚未生效", e);
		} catch (CertificateException e) {
			throw new RuntimeException("无效的证书", e);
		}
	}

}


相关参数解释

  • 可以在这个文档中心去看官方的解释
  • 下面我给出了一些比较容易混淆的参数对应的解释

请求分账API - 分账 | 微信支付商户文档中心

  1. appid - 公众账号ID
  • 微信分配的服务商appid
  1. out_order_no - 商户分账单号
  • 服务商系统内部的分账单号,在服务商系统内部唯一,
  • 同一分账单号多次请求等同一次。只能是数字、大小写字母_-|*@
  1. transaction_id - 微信订单号
  • 微信支付订单号, 即微信支付成功之后由微信返回的唯一订单号
  1. order_id - 微信分账单号
  • 微信分账单号,微信系统返回的唯一标识
  • 这是微信分账之后微信服务器返回的分账账单唯一ID
  • 这个微信分账单号和自己系统生成的**out_order_no**是等效的
  1. out_return_no - 商户回退单号
  • 此回退单号是商户在自己后台生成的一个新的回退单号,在商户后台唯一

Controller控制器

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

/**
 * @author Ccoo
 * 2024/8/16
 */
@Api(tags = "分账接口(API-V3)")
@RestController
@RequestMapping("/profitsharing")
@RequiredArgsConstructor
public class SharingController {

	private final SharingService sharingService;

	/** 添加分账接收方 */
	@ApiOperation(value = "添加分账接收方", notes = "添加分账接收方")
	@PostMapping("/addReceiver")
	public R<?> addReceiver(@ApiParam("接收方类型") @RequestParam String type,
	                        @ApiParam("接收方账号") @RequestParam String account,
	                        @ApiParam("与分账方的关系类型") @RequestParam String relationType) {
		return sharingService.addReceiver(type, account, relationType);
	}

	/** 删除分账接收方 */
	@ApiOperation(value = "删除分账接收方", notes = "删除分账接收方")
	@PostMapping("/deleteReceiver")
	public R<?> deleteReceiver(@ApiParam("接收方类型") @RequestParam String type,
	                           @ApiParam("接收方账号") @RequestParam String account) {
		return sharingService.deleteReceiver(type, account);
	}

	/** 单次分账请求 */
	@ApiOperation(value = "单次分账请求", notes = "单次分账请求")
	@PostMapping("/ordersSharing")
	public R<?> ordersSharing(@ApiParam("微信订单号") @RequestParam String transactionId,
	                          @ApiParam("分账描述") @RequestParam String description,
	                          @ApiParam("是否解冻剩余未分资金(0是,1否)") @RequestParam String unfreezeUnsplit) {
		return sharingService.ordersSharing(transactionId, description, unfreezeUnsplit);
	}

	/** 查询分账结果 */
	@ApiOperation(value = "查询分账结果", notes = "查询分账结果")
	@GetMapping("/sharingResult")
	public R<?> sharingResult(@ApiParam("商户分账单号") @RequestParam String outOrderNo,
	                          @ApiParam("微信订单号") @RequestParam String transactionId) {
		return sharingService.sharingResult(outOrderNo, transactionId);
	}

	/** 请求分账回退 */
	@ApiOperation(value = "请求分账回退", notes = "请求分账回退")
	@PostMapping("/returnSharing")
	public R<?> returnSharing(@ApiParam("微信分账单号") @RequestParam String orderId,
	                          @ApiParam("回退商户号") @RequestParam String returnMchid,
	                          @ApiParam("回退描述") @RequestParam String description){
		return sharingService.returnSharing(orderId, returnMchid, description);
	}

	/** 查询分账回退结果 */
	@ApiOperation(value = "查询分账回退结果", notes = "查询分账回退结果")
	@GetMapping("/returnSharingResult")
	public R<?> returnSharingResult(@ApiParam("商户回退单号") @RequestParam String outReturnNo,
	                                @ApiParam("商户分账单号") @RequestParam String outOrderNo) {
		return sharingService.returnSharingResult(outReturnNo, outOrderNo);
	}

	/** 解冻剩余资金 */
	@ApiOperation(value = "解冻剩余资金", notes = "解冻剩余资金")
	@PostMapping("/unfreeze")
	public R<?> unfreeze(@ApiParam("微信订单号") @RequestParam String transactionId,
	                     @ApiParam("商户分账单号") @RequestParam String outOrderNo,
	                     @ApiParam("分账描述") @RequestParam String description) {
		return sharingService.unfreeze(transactionId, outOrderNo, description);
	}


	/** 查询剩余待分金额 */
	@ApiOperation(value = "查询剩余待分金额", notes = "查询剩余待分金额")
	@GetMapping("/sharingAmountBalance")
	public R<?> sharingAmountBalance(@ApiParam("微信订单号") @RequestParam String transactionId) {
		return sharingService.sharingAmountBalance(transactionId);
	}

	/** 查询分账比例 */
	@ApiOperation(value = "查询分账比例", notes = "查询分账比例")
	@GetMapping("/sharingRatio")
	public R<?> sharingRatio(@ApiParam("商户号") @RequestParam String mchId) {
		return sharingService.sharingRatio(mchId);
	}

	/** 下载分账账单 */
	@ApiOperation(value = "下载分账账单", notes = "下载分账账单")
	@PostMapping("/downloadBill")
	public R<?> downloadBill(@ApiParam("账单日期(格式YYYY-MM-DD)") @RequestParam String billDate,
	                         @ApiParam("(选填)账单类型(不传默认为xlsx, 传GZIP则为压缩包)") String billType) {
		return sharingService.downloadBill(billDate, billType);
	}

}


Service接口层

import com.itheima.mp.domain.R;

/**
 * @author Ccoo
 * 2024/8/17
 */
public interface SharingService {

	/**
	 * 添加分账接收方
	 * @param type 接收方类型
	 * @param account 接收方账号
	 * @param relationType 分账关系类型
	 * @return 结果
	 */
	R<?> addReceiver(String type, String account, String relationType);

	/**
	 * 删除分账接收方
	 * @param type 接收方类型
	 * @param account 接收方账号
	 * @return 结果
	 */
	R<?> deleteReceiver(String type, String account);

	/**
	 * 单次请求分账
	 * @param transactionId 微信订单号
	 * @param description 分账描述
	 * @param unfreezeUnsplit 是否解冻剩余未分资金
	 * @return 结果
	 */
	R<?> ordersSharing(String transactionId, String description, String unfreezeUnsplit);

	/**
	 * 查询分账结果
	 * @param outOrderNo 商户分账单号
	 * @param transactionId 微信订单号
	 * @return 结果
	 */
	R<?> sharingResult(String outOrderNo, String transactionId);

	/**
	 * 请求分账回退
	 * @param orderId 微信分账单号
	 * @param returnMchid 回退商户号
	 * @param description 回退描述
	 * @return 结果
	 */
	R<?> returnSharing(String orderId, String returnMchid, String description);

	/**
	 * 查询分账回退结果
	 * @param outReturnNo 商户回退单号
	 * @param outOrderNo 商户订单号
	 * @return 结果
	 */
	R<?> returnSharingResult(String outReturnNo, String outOrderNo);

	/**
	 * 解冻剩余资金
	 * @param transactionId 微信订单号
	 * @param outOrderNo 商户分账单号
	 * @param description 描述信息
	 * @return 结果
	 */
	R<?> unfreeze(String transactionId, String outOrderNo, String description);

	/**
	 * 查询剩余待分金额
	 * @param transactionId 微信订单号
	 * @return 结果
	 */
	R<?> sharingAmountBalance(String transactionId);

	/**
	 * 查询分账比例
	 * @param mchId 商户号
	 * @return 结果
	 */
	R<?> sharingRatio(String mchId);

	/**
	 * 下载分账账单
	 * @param billDate 分账账单日期
	 * @param billType 分账账单类型
	 * @return 结果
	 */
	R<?> downloadBill(String billDate, String billType);

}




ServiceImpl实现层

import com.wechat.pay.java.core.exception.ServiceException;
import com.wechat.pay.java.service.profitsharing.ProfitsharingService;
import com.wechat.pay.java.service.profitsharing.model.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * @author Ccoo
 * 2024/8/17
 */
@Service
@RequiredArgsConstructor
public class SharingServiceImpl implements SharingService {

	private final ProfitsharingService profitsharingService;
	private final WxProperties wxProperties;

	public static final String TRUE_UNFREEZE_UNSPLIT = "0";
	public static final String FALSE_UNFREEZE_UNSPLIT = "1";

	/**
	 * 添加分账接收方
	 * @param type 接收方类型
	 * @param account 接收方账号
	 * @param relationType 分账关系类型
	 * @return 结果
	 * 商户发起添加分账接收方请求,建立分账接收方列表。后续可通过发起分账请求,将分账方商户结算后的资金,分到该分账接收方
	 * 商户需确保向微信支付传输用户身份信息和账号标识信息做一致性校验已合法征得用户授权
	 */
	@Override
	public R<?> addReceiver(String type, String account, String relationType) {

		AddReceiverRequest request = new AddReceiverRequest();
		// 设置APPID
		request.setAppid(wxProperties.getAppId());
		// 设置分账接收方账号
		request.setAccount(account);

		// 设置分账接收方
		if(SharingReceiverType.MERCHANT_ID.equals(type)){
			request.setType(ReceiverType.MERCHANT_ID);
		} else if (SharingReceiverType.PERSONAL_OPENID.equals(type)) {
			request.setType(ReceiverType.PERSONAL_OPENID);
		} else if (SharingReceiverType.PERSONAL_SUB_OPENID.equals(type)) {
			request.setType(ReceiverType.PERSONAL_SUB_OPENID);
		}

		// 设置分账关系类型
		if (SharingReceiverRelationType.SERVICE_PROVIDER.equals(relationType)) {
			request.setRelationType(ReceiverRelationType.SERVICE_PROVIDER);
		} else if (SharingReceiverRelationType.STORE.equals(relationType)) {
			request.setRelationType(ReceiverRelationType.STORE);
		} else if (SharingReceiverRelationType.STAFF.equals(relationType)) {
			request.setRelationType(ReceiverRelationType.STAFF);
		} else if (SharingReceiverRelationType.STORE_OWNER.equals(relationType)) {
			request.setRelationType(ReceiverRelationType.STORE_OWNER);
		} else if (SharingReceiverRelationType.PARTNER.equals(relationType)) {
			request.setRelationType(ReceiverRelationType.PARTNER);
		} else if (SharingReceiverRelationType.HEADQUARTER.equals(relationType)) {
			request.setRelationType(ReceiverRelationType.HEADQUARTER);
		} else if (SharingReceiverRelationType.BRAND.equals(relationType)) {
			request.setRelationType(ReceiverRelationType.BRAND);
		} else if (SharingReceiverRelationType.DISTRIBUTOR.equals(relationType)) {
			request.setRelationType(ReceiverRelationType.DISTRIBUTOR);
		} else if (SharingReceiverRelationType.USER.equals(relationType)) {
			request.setRelationType(ReceiverRelationType.USER);
		} else if (SharingReceiverRelationType.SUPPLIER.equals(relationType)) {
			request.setRelationType(ReceiverRelationType.SUPPLIER);
		} else if (SharingReceiverRelationType.CUSTOM.equals(relationType)) {
			request.setRelationType(ReceiverRelationType.CUSTOM);
		}

		try {
			// 请求微信服务器添加分账接收方
			AddReceiverResponse response = profitsharingService.addReceiver(request);
			return R.ok(response);
		} catch (ServiceException e) {
			return R.fail(e.getHttpStatusCode(), e.getErrorMessage());
		}

	}

	/**
	 * 删除分账接收方
	 * @param type 接收方类型
	 * @param account 接收方账号
	 * @return 结果
	 * 商户发起删除分账接收方请求。删除后,不支持将分账方商户结算后的资金,分到该分账接收方
	 */
	@Override
	@Transactional
	public R<?> deleteReceiver(String type, String account) {

		DeleteReceiverRequest request = new DeleteReceiverRequest();
		// 设置APPID
		request.setAppid(wxProperties.getAppId());
		// 设置分账接收方账号
		request.setAccount(account);

		// 设置分账接收方类型
		if(SharingReceiverType.MERCHANT_ID.equals(type)){
			request.setType(ReceiverType.MERCHANT_ID);
		} else if (SharingReceiverType.PERSONAL_OPENID.equals(type)) {
			request.setType(ReceiverType.PERSONAL_OPENID);
		} else if (SharingReceiverType.PERSONAL_SUB_OPENID.equals(type)) {
			request.setType(ReceiverType.PERSONAL_SUB_OPENID);
		}

		try {
			// 请求微信服务器删除分账接收方
			DeleteReceiverResponse response = profitsharingService.deleteReceiver(request);
			return R.ok(response);
		} catch (ServiceException e) {
			return R.fail(e.getHttpStatusCode(), e.getErrorMessage());
		}

	}

	/**
	 * 单次分账请求
	 *
	 * @return 结果
	 * 微信订单支付成功后,商户发起分账请求,将结算后的资金分到分账接收方
	 * 对同一笔订单最多能发起50次分账请求,每次请求最多分给50个接收方
	 * 此接口采用异步处理模式,即在接收到商户请求后,会先受理请求再异步处理,最终的分账结果可以通过查询分账接口获取
	 * 商户需确保向微信支付传输用户身份信息和账号标识信息做一致性校验已合法征得用户授权
	 */
	@Override
	@Transactional
	public R<?> ordersSharing(String transactionId, String description, String unfreezeUnsplit) {
		CreateOrderRequest request = new CreateOrderRequest();
		String outOrderNo = System.currentTimeMillis() + String.valueOf(new Random().nextInt(999999));

		// 设置APPID
		request.setAppid(wxProperties.getAppId());
		// 设置微信订单号
		request.setTransactionId(transactionId);
		// 设置商户订单号
		request.setOutOrderNo(outOrderNo);

		List<CreateOrderReceiver> receivers = new ArrayList<>();
		// 设置分账接收方, 可以为多个分账接收方, 这里测试只设置一个
		CreateOrderReceiver receiver1 = new CreateOrderReceiver();
		// 设置分账接收方类型
		receiver1.setType("PERSONAL_OPENID");
		// 设置分账接收方账号, 换成自己的接收方账号
		receiver1.setAccount("oWBG560SZ8P_xxxxxxxxxxxxxx");
		// 设置分账金额, 这里测试金额为1分, 默认最高只能分订单的30%
		receiver1.setAmount(1L);
		// 设置分账描述
		receiver1.setDescription(description);
		// 设置分账接收方列表
		receivers.add(receiver1);
		request.setReceivers(receivers);

		// 设置是否解冻剩余资金
		if (TRUE_UNFREEZE_UNSPLIT.equals(unfreezeUnsplit)) request.setUnfreezeUnsplit(Boolean.TRUE);
		if (FALSE_UNFREEZE_UNSPLIT.equals(unfreezeUnsplit)) request.setUnfreezeUnsplit(Boolean.FALSE);

		try {
			// 请求微信服务器发起分账请求
			OrdersEntity response = profitsharingService.createOrder(request);
			return R.ok(response);
		} catch (ServiceException e) {
			return R.fail(e.getHttpStatusCode(), e.getErrorMessage());
		}

	}

	/**
	 * 查询分账结果
	 * @param outOrderNo 商户分账单号
	 * @param transactionId 微信订单号
	 * @return 结果
	 * 发起分账请求后,可调用此接口查询分账结果
	 * 发起解冻剩余资金请求后,可调用此接口查询解冻剩余资金的结果
	 */
	@Override
	@Transactional
	public R<?> sharingResult(String outOrderNo, String transactionId) {
		QueryOrderRequest request = new QueryOrderRequest();

		// 1. 设置微信订单号
		request.setTransactionId(transactionId);
		// 2. 设置商户订单号
		request.setOutOrderNo(outOrderNo);

		try {
			// 请求微信服务器查询分账结果
			OrdersEntity response = profitsharingService.queryOrder(request);
			return R.ok(response);
		} catch (ServiceException e) {
			return R.fail(e.getHttpStatusCode(), e.getErrorMessage());
		}


	}

	/**
	 * 请求分账回退
	 * @param orderId 微信分账单号
	 * @param returnMchid 回退商户号
	 * @param description 回退描述
	 * @return 结果
	 * 如果订单已经分账,在退款时,可以先调此接口,将已分账的资金从分账接收方的账户回退给分账方,再发起退款。
	 * 分账回退以原分账单为依据,支持多次回退,申请回退总金额不能超过原分账单分给该接收方的金额
	 * 此接口采用同步处理模式,即在接收到商户请求后,会实时返回处理结果
	 * 对同一笔分账单最多能发起20次分账回退请求
	 * 退款和分账回退没有耦合,分账回退可以先于退款请求,也可以后于退款请求
	 * 此功能需要接收方在商户平台-交易中心-分账-分账接收设置下,开启同意分账回退后,才能使用
	 * 不支持针对“分账到零钱”的分账单发起分账回退。
	 * 分账回退的时限是180天。
	 */
	@Override
	public R<?> returnSharing(String orderId, String returnMchid, String description) {
		CreateReturnOrderRequest request = new CreateReturnOrderRequest();
		// 生成商户回退单号
		String outReturnNo = System.currentTimeMillis() + String.valueOf(new Random().nextInt(999999));

		// 设置微信分账单号
		request.setOrderId(orderId);
		// 设置回退商户号
		request.setReturnMchid(returnMchid);
		// 设置商户回退单号
		request.setOutReturnNo(outReturnNo);
		// 设置回退金额, 这里测试金额为1分
		request.setAmount(1L);
		// 设置回退描述
		request.setDescription(description);

		try {
			// 请求微信服务器发起分账回退请求
			ReturnOrdersEntity response = profitsharingService.createReturnOrder(request);
			return R.ok(response);
		} catch (ServiceException e) {
			return R.fail(e.getHttpStatusCode(), e.getErrorMessage());
		}

	}

	/**
	 * 查询分账回退结果
	 * @param outReturnNo 商户回退单号
	 * @param outOrderNo 商户订单号
	 * @return 结果
	 * 商户需要核实回退结果,可调用此接口查询回退结果。
	 * 如果分账回退接口返回状态为处理中,可调用此接口查询回退结果
	 */
	@Override
	public R<?> returnSharingResult(String outReturnNo, String outOrderNo) {
		QueryReturnOrderRequest request = new QueryReturnOrderRequest();
		// 1. 设置商户回退单号
		request.setOutReturnNo(outReturnNo);
		// 2. 设置商户订单号
		request.setOutOrderNo(outOrderNo);

		try {
			// 请求微信服务器查询分账回退结果
			ReturnOrdersEntity response = profitsharingService.queryReturnOrder(request);
			return R.ok(response);
		} catch (ServiceException e) {
			return R.fail(e.getHttpStatusCode(), e.getErrorMessage());
		}
	}

	/**
	 * 解冻剩余资金
	 * @param transactionId 微信订单号
	 * @param outOrderNo 商户分账单号
	 * @param description 描述信息
	 * @return 结果
	 * 不需要进行分账的订单,可直接调用本接口将订单的金额全部解冻给本商户
	 * 调用分账接口后,需要解冻剩余资金时,调用本接口将剩余的分账金额全部解冻给本商户
	 * 此接口采用异步处理模式,即在接收到商户请求后,优先受理请求再异步处理,最终的分账结果可以通过查询分账接口获取
	 */
	@Override
	public R<?> unfreeze(String transactionId, String outOrderNo, String description) {
		UnfreezeOrderRequest request = new UnfreezeOrderRequest();

		// 1. 设置微信订单号
		request.setTransactionId(transactionId);
		// 2. 设置商户订单号
		request.setOutOrderNo(outOrderNo);
		// 3. 设置描述信息
		request.setDescription(description);

		try {
			// 请求微信服务器发起解冻剩余资金请求
			OrdersEntity response = profitsharingService.unfreezeOrder(request);
			return R.ok(response);
		} catch (ServiceException e) {
			return R.fail(e.getHttpStatusCode(), e.getErrorMessage());
		}
	}

	/**
	 * 查询剩余待分金额
	 * @param transactionId 微信订单号
	 * @return 结果
	 * 可调用此接口查询订单剩余待分金额
	 */
	@Override
	public R<?> sharingAmountBalance(String transactionId) {
		QueryOrderAmountRequest request = new QueryOrderAmountRequest();

		// 设置微信订单号
		request.setTransactionId(transactionId);

		try {
			// 请求微信服务器查询剩余待分金额
			QueryOrderAmountResponse response = profitsharingService.queryOrderAmount(request);
			return R.ok(response);
		} catch (ServiceException e) {
			return R.fail(e.getHttpStatusCode(), e.getErrorMessage());
		}
	}

	/**
	 * 查询分账比例
	 * @param mchId 商户号
	 * @return 结果
	 */
	@Override
	public R<?> sharingRatio(String mchId) {

		QueryMerchantRatioRequest request = new QueryMerchantRatioRequest();
		// 设置分账接收方商户号
		request.setSubMchid(mchId);

		try {
			// 请求微信服务器查询分账比例
			QueryMerchantRatioResponse response = profitsharingService.queryMerchantRatio(request);
			return R.ok(response);
		} catch (ServiceException e) {
			return R.fail(e.getHttpStatusCode(), e.getErrorMessage());
		}
	}

	/**
	 * 下载分账账单
	 * @param billDate 分账账单日期
	 * @param billType 分账账单类型
	 * @return 结果
	 * 微信支付按天提供分账账单文件,商户可以通过该接口获取账单文件的下载地址。文件内包含分账相关的金额、时间等信息,供商户核对到账等情况
	 * 微信侧未成功的分账单不会出现在对账单中。
	 * 对账单中涉及金额的字段单位为“元”;
	 * 对账单接口只能下载三个月以内的账单。
	 * 账单文件包括明细数据和汇总数据两部分,每一部分都包含一行表头和若干行具体数据。
	 * 明细数据每一行对应一笔分账或一笔回退,同时每一个数据前加入了字符`,以避免数据被Excel按科学计数法处理。如需汇总金额等数据,可以批量替换掉该字符
	 */
	@Override
	public R<?> downloadBill(String billDate, String billType) {
		SplitBillRequest request = new SplitBillRequest();
		// 1. 设置账单日期
		request.setBillDate(billDate);
		if(billType != null && !billType.isEmpty()){
			// 2. 设置账单类型
			request.setTarType(SplitBillTarType.GZIP);
		}

		try {
			// 请求微信服务器下载分账账单
			SplitBillResponse response = profitsharingService.splitBill(request);
			return R.ok(response);
		} catch (ServiceException e) {
			return R.fail(e.getHttpStatusCode(), e.getErrorMessage());
		}
	}

}


常量类集合

  1. SharingReceiverType
/**
 * @author Ccoo
 * 2024/3/8
 */
public class SharingReceiverType {

	/**
	 * 商户号
	 */
	public static final String MERCHANT_ID = "MERCHANT_ID";

	/**
	 * 个人OpenID
	 */
	public static final String PERSONAL_OPENID = "PERSONAL_OPENID";

	/**
	 * 个人SubOpenID
	 */
	public static final String PERSONAL_SUB_OPENID = "PERSONAL_SUB_OPENID";

}

  1. SharingReceiverRelationType
/**
 * @author Ccoo
 * 2024/3/8
 */
public class SharingReceiverRelationType {

	/**
	 * 服务商
	 */
	public static final String SERVICE_PROVIDER = "SERVICE_PROVIDER";

	/**
	 * 门店
	 */
	public static final String STORE = "STORE";

	/**
	 * 员工
	 */
	public static final String STAFF = "STAFF";

	/**
	 * 店主
	 */
	public static final String STORE_OWNER = "STORE_OWNER";

	/**
	 * 合作伙伴
	 */
	public static final String PARTNER = "PARTNER";

	/**
	 * 总部
	 */
	public static final String HEADQUARTER = "HEADQUARTER";

	/**
	 * 品牌方
	 */
	public static final String BRAND = "BRAND";

	/**
	 * 分销商
	 */
	public static final String DISTRIBUTOR = "DISTRIBUTOR";

	/**
	 * 用户
	 */
	public static final String USER = "USER";

	/**
	 * 供应商
	 */
	public static final String SUPPLIER = "SUPPLIER";

	/**
	 * 自定义
	 */
	public static final String CUSTOM = "CUSTOM";

}


  1. R 统一响应类
import java.io.Serializable;

/**
 * 响应信息主体
 *
 * @author Ccoo
 */
public class R<T> implements Serializable
{
    private static final long serialVersionUID = 1L;

    /** 成功 */
    public static final int SUCCESS = 200;

    /** 失败 */
    public static final int FAIL = 500;

    private int code;

    private String msg;

    private T data;

    public static <T> R<T> ok()
    {
        return restResult(null, SUCCESS, "操作成功");
    }
    public static <T> R<T> ok(String msg)
    {
        return restResult(null, SUCCESS, msg);
    }

    public static <T> R<T> ok(T data)
    {
        return restResult(data, SUCCESS, "操作成功");
    }

    public static <T> R<T> ok(T data, String msg)
    {
        return restResult(data, SUCCESS, msg);
    }

    public static <T> R<T> fail()
    {
        return restResult(null, FAIL, "操作失败");
    }

    public static <T> R<T> fail(String msg)
    {
        return restResult(null, FAIL, msg);
    }

    public static <T> R<T> fail(T data)
    {
        return restResult(data, FAIL, "操作失败");
    }

    public static <T> R<T> fail(T data, String msg)
    {
        return restResult(data, FAIL, msg);
    }

    public static <T> R<T> fail(int code, String msg)
    {
        return restResult(null, code, msg);
    }

    private static <T> R<T> restResult(T data, int code, String msg)
    {
        R<T> apiResult = new R<>();
        apiResult.setCode(code);
        apiResult.setData(data);
        apiResult.setMsg(msg);
        return apiResult;
    }

    public int getCode()
    {
        return code;
    }

    public void setCode(int code)
    {
        this.code = code;
    }

    public String getMsg()
    {
        return msg;
    }

    public void setMsg(String msg)
    {
        this.msg = msg;
    }

    public T getData()
    {
        return data;
    }

    public void setData(T data)
    {
        this.data = data;
    }
    
}

标签:return,String,微信,对接,request,分账,public
From: https://blog.csdn.net/apple_74262176/article/details/141497475

相关文章

  • 校园小情书微信小程序源码 | 社区小程序前后端开源 | 校园表白墙交友小程序
    校园小情书微信小程序源码 | 社区小程序前后端开源 | 校园表白墙交友小程序【校园小情书】——用代码编织的青春告白在这个数字化的时代,我们的情感表达也逐渐从纸笔转向了屏幕。小红书上的小伙伴们,你们是否也曾幻想过,在校园的某个角落,有一个属于自己的表白墙,可以匿名或实......
  • 微信支付发起退款时,异常解决
    保证自身服务代码正常情况下微信发起退款的异常分两种第一种是业务异常:账户余额不足等退款失败|或者超额退款失败第二种是网络异常:创建微信Config时会执行一次微信校验;会调用api.mch.weixin.qq.com校验|还有真实发起退款可能也会因为api.mch.weixin.qq.com的DNS解析出错导......
  • 微信私域&SEO运营神器,9款RPA机器人上线
    上一期我们分享了7款抖音RPA机器人,很多爪爪们都开始用了起来......
  • 基于STM32设计的智能饮水机_升级版(微信小程序)(213)
    文章目录一、前言1.1项目介绍【1】项目功能介绍【2】设计实现的功能【3】项目硬件模块组成1.2设计思路【1】整体设计思路【2】ESP8266工作模式配置1.3项目开发背景【1】选题的意义【2】可行性分析【3】参考文献【4】摘要【5】选题背景【6......
  • 微信开发者工具启用Mock模拟网络请求
    当开发微信小程序在后端接口还没开发好的情况下,想要进行接口调试怎么办?微信开发者工具提供了Mock功能,方便开发者模拟网络请求提前调试。1、在调试器中选Mock2、启用Mock3、新建规则API接口选择request(网络请求)类型参数规则匹配,填写正确的url正则匹配规则(包含参数)模......
  • NETCORE下用SKIT类库发送微信模板消息
    NETCORE下用SKIT类库发送微信模板消息 //测试发送模板消息-微信公众号//https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Template_Message_Interface.html#5publicasyncTask<IActionResult>Ceshi(intid,stringopenid)......
  • 超实用技巧!微信小程序圆码转换方形黑白二维码
    如今二维码在各行各业都被广泛应用,好多平台为了方便分享,都能把个人账号主页、发布的视频/文章、上架的商品等生成二维码,微信小程序自然也不例外。有些朋友因为二维码的应用场景比较复杂,就想把小程序的圆形二维码变成常规的方形二维码,这该咋整呢?其实很简单!我们把圆码变成二......
  • 微信小程序 BLE 基础业务接口封装
    写在前面:本文所述未必符合当前最新情形(包括蓝牙技术发展、微信小程序接口迭代等)。微信小程序为蓝牙操作提供了很多接口,但在实际开发过程中,会发现隐藏了不少坑。目前主流蓝牙应用都是基于低功耗蓝牙(BLE)的,本文介绍相关的几个基础接口,并对其进行封装,便于业务层调用。蓝牙发展在开......
  • 微信小程序for循环怎么用
    微信for简单使用: <view>    <ul>        <li wx:for="{{xiaoke}}" wx:key="index">            <a href="{{item.path}}">{{item.name}}</a>        </li>    </ul></view>其中"xiao......
  • [开题]flask框架信息安全知识学习微信小程序10fhc(程序+论文+python)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景在数字化时代,信息安全已成为社会经济发展的重要基石。随着移动互联网的普及,微信小程序作为一种轻量级的应用形态,迅速渗透到人们的日常生活......