All checks were successful
Publish to Confluence / confluence (push) Successful in 1m20s
6.8 KiB
6.8 KiB
电商订单对接指南
- eBay 接入指南可以查看:http://confluence.qifu.com/pages/viewpage.action?pageId=38511846
- TikTok 接入指南可以查看:http://confluence.qifu.com/pages/viewpage.action?pageId=38512736
- Amazon 接入指南可以查看:http://confluence.qifu.com/pages/viewpage.action?pageId=38512738
- Lazada 接入指南可以查看:http://confluence.qifu.com/pages/viewpage.action?pageId=38512740
使用南北流量网关对接电商平台
接口交互流程
电商用户授权流程
接口交互流程
添加依赖
<dependencys>
<!-- RPC接口 -->
<dependency>
<groupId>com.yuanmeng.qifu</groupId>
<artifactId>qifu-saas-eg-client</artifactId>
<version>1.0.13</version>
</dependency>
<!-- SPI接收订单同步信息 -->
<dependency>
<groupId>com.yuanmeng.qifu</groupId>
<artifactId>qifu-saas-eg-spi</artifactId>
<version>1.0.13</version>
</dependency>
</dependencys>
注册SPI服务(注册之后才会有 webhook 请求)
spi包中包含的自动注册
- qifu-saas-eg-spi 已经整合了自动注册功能。
- 默认以 spring.application.name 作为服务名在程序启动时发起注册
- 可以做特殊配置:
-
qifu: eg: spi: enable: true enable-spi-register: true spi-infos: - type: 1 server-code: ${spring.application.name} server-name: ${spring.application.name} server-description: '测试服务'
- type:1=订单同步SPI
- server-code:唯一标识,卖家授权的时候使用
- server-name:服务名称,SPI feign调用服务名
手动注册
- 使用
RemoteSpiService.addSpi
来进行注册 - 可以关闭自动注册
-
qifu: eg: spi: enable-spi-register: false
卖家授权(必须)
第一步:关联卖家授权应用(必须)
RemoteOrderService.linkApp(channel, sellerId, region, orderAppId, spiServerCodes)
- channel
(required)
: 渠道,参考OrderChannelEnum
code字段 - sellerId
(required)
:卖家id,卖家唯一标识,业务自定义 - region
(required)
:所属区域,请看RemoteOrderService.linkApp()
接口文档注释 - orderAppId
(optional)
:关联的授权应用,没传由系统负载获取 - spiServerCodes
(optional)
:spi回调应用编码,多个用, 分割,没有时不会做 webhook - 示例:
-
curl -X POST --location "http://localhost:8933/order/app/link?channel=4&sellerId=keyfil001®ion=Vietnam" \ -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYmYiOjE3MzEzODIxNzksInRlbmFudElkIjo3LCJuaWNrbmFtZSI6IuWImOaZk-WNjiIsImV4cCI6MTczMTQyNTM3OSwiaWF0IjoxNzMxMzgyMTc5LCJ1c2VySWQiOjEzODM3MjksImp0aSI6ImYyMzQ1NDgxNWQ0NTRkNzk4MGQ2ZjQwMGQ2NWFlMzBkIn0.QjFcqlGACbR9VZXEyQhmuP-JTJTT7ILmP8FeNdGJcJI"
获取授权链接(必须)
RemoteOrderService.authAuthorizeUrl(Integer channel, String sellerId)
- 示例:
-
curl -X GET --location "http://localhost:8933/order/oauth/authorize?channel=4&sellerId=keyfil001" \ -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYmYiOjE3MzEzODIxNzksInRlbmFudElkIjo3LCJuaWNrbmFtZSI6IuWImOaZk-WNjiIsImV4cCI6MTczMTQyNTM3OSwiaWF0IjoxNzMxMzgyMTc5LCJ1c2VySWQiOjEzODM3MjksImp0aSI6ImYyMzQ1NDgxNWQ0NTRkNzk4MGQ2ZjQwMGQ2NWFlMzBkIn0.QjFcqlGACbR9VZXEyQhmuP-JTJTT7ILmP8FeNdGJcJI"
获取accessToken(回调链接为业务链接时必须)
RemoteOrderService.authAccessToken(Integer channel, String appName, String code, String spapiOauthCode, String shopId, String mainAccountId, String state)
- 示例:
-
curl -X GET --location "http://localhost:8933/open/order/oauth/callback/4?code=0_132783_8fmfr7mGBVhjyFt7aycC8R784464&state=1922598474703364098"
授权状态(必须)(快过期时提醒用户重新授权)
- 在授权后需要查询授权状态,授权状态快过期时需要提醒用户重新授权
RemoteOrderService.oauthStatus(Integer channel, String sellerId)
- 示例:
-
curl -X GET --location "http://localhost:8933/order/oauth/status?channel=4&sellerId=keyfil001"
手动同步(可选)
- 手动触发订单同步操作
RemoteOrderService.syncOrder(OrderSyncReq req)
- 示例:
-
curl -X POST --location "http://localhost:8933/order/sync" \ -H "Content-Type: application/json" \ -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJuYmYiOjE3MzEzODIxNzksInRlbmFudElkIjo3LCJuaWNrbmFtZSI6IuWImOaZk-WNjiIsImV4cCI6MTczMTQyNTM3OSwiaWF0IjoxNzMxMzgyMTc5LCJ1c2VySWQiOjEzODM3MjksImp0aSI6ImYyMzQ1NDgxNWQ0NTRkNzk4MGQ2ZjQwMGQ2NWFlMzBkIn0.QjFcqlGACbR9VZXEyQhmuP-JTJTT7ILmP8FeNdGJcJI" \ -d '{ "channel": 4, "sellerId": "keyfil001", "startTimeMillis": 1742529814000 }'
自动同步
- 每一个小时会进行一次订单同步。cron:
0 0 0/1 * * ?
编写SPI处理逻辑
开放接口
- SPI通过自动注册接口
/sync/order/change
来实现 webhook 请求接收 - 需要程序开放
/sync/order/change
接口供qifu-saas-eg
回调使用
编写回调信息处理逻辑
- 实现
OrderSyncHandler
- 示例:
-
@Slf4j @Component public class OrderSyncHandlerImpl implements OrderSyncHandler { @Override public Boolean handle(SpiOrderReq req) { log.info("channel: {}", req.getChannel()); log.info("sellerId: {}", req.getSellerId()); log.info("orders: {}", req.getSpiOrders()); for (SpiOrderReq.SpiOrder spiOrder : req.getSpiOrders()) { if (spiOrder.getOldOrder() == null) { // TODO 新订单处理逻辑 log.info("new order handler: order info: {}", spiOrder.getNewOrder()); } else { // TODO 更新订单逻辑 log.info("update order handler: old order info: {}", spiOrder.getOldOrder()); log.info("update order handler: new order info: {}", spiOrder.getNewOrder()); } } return Boolean.TRUE; } }