当前位置:网站首页>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;
}
}
边栏推荐
- Redis master-slave mode
- 投资理财适合女生吗?女生可以买哪些理财产品?
- Learn the garbage collector of JVM -- a brief introduction to Shenandoah collector
- How to recover the information server and how to recover the server data [easy to understand]
- Application of a class of identities (vandermond convolution and hypergeometric functions)
- Conversion du format de données GPS [facile à comprendre]
- GPS数据格式转换[通俗易懂]
- 1 plug-in to handle advertisements in web pages
- Differences between IPv6 and IPv4 three departments including the office of network information technology promote IPv6 scale deployment
- HiEngine:可媲美本地的云原生内存数据库引擎
猜你喜欢
MySQL splits strings for conditional queries
The survey shows that traditional data security tools cannot resist blackmail software attacks in 60% of cases
Learn the memory management of JVM 02 - memory allocation of JVM
Wireless WiFi learning 8-channel transmitting remote control module
什么是数字化存在?数字化转型要先从数字化存在开始
Pytorch weight decay and dropout
Reading notes of growth hacker
你做自动化测试为什么总是失败?
July Huaqing learning-1
[upsampling method opencv interpolation]
随机推荐
The evolution of mobile cross platform technology
Multi table operation - Auto Association query
Troubleshooting of high memory usage of redis in a production environment
Video networkState 属性
JS for loop number exception
POJ-2499 Binary Tree
Halcon template matching actual code (I)
vscode快捷键
MySQL installation, Windows version
Learn the memory management of JVM 02 - memory allocation of JVM
Image hyperspectral experiment: srcnn/fsrcnn
调查显示传统数据安全工具在60%情况下无法抵御勒索软件攻击
[hdu 2096] Xiaoming a+b
Codeworks 5 questions per day (1700 average) - day 5
Understand kotlin from the perspective of an architect
【ijkplayer】when i compile file “compile-ffmpeg.sh“ ,it show error “No such file or directory“.
Embedded software architecture design - message interaction
Learn JVM garbage collection 02 - a brief introduction to the reference and recycling method area
[loss functions of L1, L2 and smooth L1]
7月华清学习-1