当前位置:网站首页>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;
}
}
边栏推荐
- POJ-2499 Binary Tree
- 手机 CPU 架构类型了解
- Learn the garbage collector of JVM -- a brief introduction to Shenandoah collector
- Get data from the database when using JMeter for database assertion
- Swift - add navigation bar
- Course design of compilation principle --- formula calculator (a simple calculator with interface developed based on QT)
- Open3d mesh (surface) coloring
- MySQL view
- Simple production of wechat applet cloud development authorization login
- 多表操作-自关联查询
猜你喜欢
The evolution of mobile cross platform technology
Take you two minutes to quickly master the route and navigation of flutter
One article tells the latest and complete learning materials of flutter
ABAP table lookup program
Matlab label2idx function (convert the label matrix into a cell array with linear index)
abap查表程序
Why do you always fail in automated tests?
Tabbar configuration at the bottom of wechat applet
Get data from the database when using JMeter for database assertion
July Huaqing learning-1
随机推荐
Video networkstate property
[untitled]
Principle of redis cluster mode
语义分割实验:Unet网络/MSRC2数据集
【ijkplayer】when i compile file “compile-ffmpeg.sh“ ,it show error “No such file or directory“.
Matlab superpixels function (2D super pixel over segmentation of image)
Linux Installation and deployment lamp (apache+mysql+php)
Design of music box based on assembly language
Tabbar configuration at the bottom of wechat applet
16 channel water lamp experiment based on Proteus (assembly language)
Error modulenotfounderror: no module named 'cv2 aruco‘
Seven ways to achieve vertical centering
JS for循环 循环次数异常
Complete activity switching according to sliding
Want to ask, how to choose a securities firm? Is it safe to open an account online?
Conversion du format de données GPS [facile à comprendre]
Matlab label2idx function (convert the label matrix into a cell array with linear index)
Application of a class of identities (vandermond convolution and hypergeometric functions)
Learn the memory management of JVM 03 - Method area and meta space of JVM
Course design of compilation principle --- formula calculator (a simple calculator with interface developed based on QT)