当前位置:网站首页>Third party payment interface design
Third party payment interface design
2022-07-05 12:17:00 【Xujunsheng】
You are a man who does great things
Preface
It is necessary to read this article 6 minute
Recently, the third-party payment has been connected in the project , For third party payments , The more complex function is payment 、 refund 、 Reconciliation .
In this article, we only introduce the interface design related to payment .
The nodes that a payment flow may involve include : payment 、 Payment result query 、 Payment result notice 、 cancel the order 、 Customs clearance 、 refund 、 Reconciliation .
Take Alipay for example , Alipay provides a very rich payment capability :app payment 、 Sweep code payment 、 Website payment, etc . There is little difference between different payment methods .
The process of docking with third-party payment is similar . According to the official documents, the docking can be completed quickly , So in this article, we will not discuss how to connect with third-party payment , We want to talk about things other than docking .
I am here How to design an interface ? It says , There are five points to consider when designing an interface : Security 、 stability 、 Efficiency 、 Maintainability 、 Readability .
Next, we will discuss how to design a payment interface around these features .
Security
The payment interface involves the flow of funds , Then its security is self-evident .
Alipay regulations , When accessing payment capacity , The data transmission interface is encrypted with public and private keys .
How can we ensure the security between our own interfaces ?
SHA256
perhaps RSA2
.
The specific encryption algorithm is not described in detail here , I'm looking for a lot on the Internet .
This article simply talks about the encryption process , Here's the picture :
To be specific :
- stay App End first
SHA256
perhapsRSA2
Encrypt the payment message , Then send it to the backstage service ; - Background parsing ciphertext , And verify that .
- If the resolution passes, proceed to the next step of logic , Otherwise, it will prompt that the ciphertext parsing fails .
stability
Idempotency is extremely important for payment interfaces .
The database operations involved in the payment business include : Save payment flow 、 Synchronize order status 、 Update inventory quantity, etc .
Due to the natural non idempotent nature of new operations , So we need to ensure at the design level .
I'm in the project Use Redis The distributed lock realizes the idempotent of the payment interface .
- About using Redis The principle of implementing distributed lock , I will share with you in the next article .
The way I implement it in the project :Redisson
.
Redisson principle :
- Thread to get lock , To be successful : perform lua Script , Save data to redis database .
- Thread to get lock , Acquisition failure : All the way through while Loop trying to get lock , Execute after success lua Script , Save data to redis database .
- Support the watchdog automatic delay mechanism .
Code instance :
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.13.6</version>
</dependency>
public void testReentrantLock(RedissonClient redisson){
RLock lock = redisson.getLock("anyLock");
try{
// 1. The most common use method
//lock.lock();
// 2. Support the function of overdue unlocking ,10 Automatically unlock after seconds , Don't need to call unlock Method to manually unlock
//lock.lock(10, TimeUnit.SECONDS);
// 3. Try to lock , Waiting for the most 3 second , After the lock 10 Seconds auto unlock
boolean res = lock.tryLock(3, 10, TimeUnit.SECONDS);
if(res){
// success
// do your business
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
In addition to idempotency , Another problem to be considered in the payment interface is Order closed over time . This question is left for you to think about first , We will introduce it in detail in a later article .
Transaction consistency
If the payment is successful, the order status should be updated 、 Inventory quantity .
In the context of microservices , The databases of each business are independent , In order to ensure the consistency of transactions, we need to use distributed transactions .
Common distributed transaction solutions :
- XA Two-phase commit
- TCC Pattern : Support TCC The open source frameworks for transactions are :ByteTCC、Himly、TCC-transaction.
- Saga Business
- Message based distributed transaction : Scheme based on transaction message 、 Local message based solutions
- Distributed transaction middleware :Seata
Maintainability
At present, only Alipay and wechat are connected in our project , In the future, it may connect with UnionPay and so on . Payment methods will continue to increase with the growth of business .
But the process of each payment method is roughly the same : Decryption of payment information 、 payment 、 Order modification 、 Modify inventory .
In this way , Use if else
Judgment will lead to high coupling between payment function and system business function .
if (payType.equals ("WeiXin")) {
//dosomething
} else if (payType.equals ("AliPay")) {
//dosomething
} else if (payType.equals ("UnionPay")) {
//dosomething
}
So I used in the project The strategy pattern , To define different implementations for different payment methods .
First, define an abstract class , Encapsulate common methods .
Then customize the annotation
ServiceRoute
, Marked in the specific payment implementation interface , When the project starts, it automatically marksServiceRoute
Annotated services are injected into the container ;At the time of payment, according to the specific channel number , Call different payment implementation functions .
Custom annotation :
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface ServiceRoute {
/** * Payment channel number * * @return */
String value();
}
Service registration :
public class RegisterService implements ApplicationContextAware {
private static final Logger logger = LoggerFactory.getLogger(RegisterService.class);
private Map<String, Object> servicesMap = new ConcurrentHashMap<String, Object>();
private static ApplicationContext applicationCtx = null;
/** * Register service interface */
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
applicationCtx = applicationContext;
// Scan added ServiceRoute Annotated classes
Map<String, Object> allWebResBeans = applicationCtx.getBeansWithAnnotation(ServiceRoute.class);
for (Object bean : allWebResBeans.values()) {
String routeName = getServiceRoute(bean);
if (routeName != null) {
servicesMap.put(routeName, bean);
logger.debug("register route,routeName={},bean={}", new Object[] {
routeName,bean});
}
}
}
private String getServiceRoute(Object bean) {
if (bean != null) {
Annotation anno = AnnotationUtils.getAnnotation(bean.getClass(), ServiceRoute.class);
if (anno != null) {
return anno.getClass().getAnnotation(ServiceRoute.class).value();
}
}
return null;
}
public Object getServiceByAnnoName(String name) {
if (StringUtils.isNotEmpty(name)) {
return servicesMap.get(name);
}
return null;
}
}
边栏推荐
- 一款新型的智能家居WiFi选择方案——SimpleWiFi在无线智能家居中的应用
- Troubleshooting of high memory usage of redis in a production environment
- 互联网公司实习岗位选择与简易版职业发展规划
- 想问问,如何选择券商?在线开户是很安全么?
- [HDU 2096] 小明A+B
- Differences between IPv6 and IPv4 three departments including the office of network information technology promote IPv6 scale deployment
- 只是巧合?苹果 iOS16 的神秘技术竟然与中国企业 5 年前产品一致!
- Redirection of redis cluster
- Embedded software architecture design - message interaction
- Multi table operation - sub query
猜你喜欢
Take you two minutes to quickly master the route and navigation of flutter
调查显示传统数据安全工具在60%情况下无法抵御勒索软件攻击
Liunx prohibit Ping explain the different usage of traceroute
Error modulenotfounderror: no module named 'cv2 aruco‘
codeforces每日5题(均1700)-第五天
Master the new features of fluent 2.10
Check the debug port information in rancher and do idea remote JVM debug
Redirection of redis cluster
Use and install RkNN toolkit Lite2 on itop-3568 development board NPU
[pytorch modifies the pre training model: there is little difference between the measured loading pre training model and the random initialization of the model]
随机推荐
JS for loop number exception
A new WiFi option for smart home -- the application of simplewifi in wireless smart home
Which domestic cloud management platform manufacturer is good in 2022? Why?
Master the new features of fluent 2.10
MySQL splits strings for conditional queries
HiEngine:可媲美本地的云原生内存数据库引擎
多表操作-子查询
byte2String、string2Byte
Open3d mesh (surface) coloring
The survey shows that traditional data security tools cannot resist blackmail software attacks in 60% of cases
多表操作-自关联查询
MySQL regular expression
Halcon template matching actual code (I)
Acid transaction theory
【ijkplayer】when i compile file “compile-ffmpeg.sh“ ,it show error “No such file or directory“.
无线WIFI学习型8路发射遥控模块
Read and understand the rendering mechanism and principle of flutter's three trees
MySQL stored procedure
一类恒等式的应用(范德蒙德卷积与超几何函数)
Get all stock data of big a