Fraud Prevention
Last updatedIntroduction#
In the current retail space, fashion e-commerce emerges as a particularly vulnerable sector to fraudulent activities. While in some cases it might be enough to lean on the fraud detection tools offered by payment providers, specialized solutions, which leverage technologies like machine learning and analyze customer behavior patterns in the checkout, can offer more robust protection.
The following article explains how to integrate any fraud prevention solution with Centra.
Understanding the transaction flows of Fraud Prevention solutions#
There are two general approaches when it comes to Fraud Prevention solutions:
-
Post-authorization fraud check - the fraud check happens after the payment request is sent to a Payment Service Provider and the payment authorization is secured; meaning, the check happens after the order is placed by the shopper. (Supported by Centra)
-
Pre-authorization fraud check - the fraud check happens before the payment request is sent to a Payment Service Provider; meaning, it happens in the checkout before the order is placed by the shopper (Not supported by Centra currently)
If you would like to integrate a solution that can handle post-authorisation fraud checks (Riskified, Signifyd or other), you can do so by following the steps below. You will need to build a custom Partner Integration in order to facilitate communication between the store and the fraud prevention solution of your choice. See the diagram below to better understand the how the flow of data works between Centra and the Partner Integration.
Centra order flow with a fraud check#
Enabling the Fraud Prevention plugin will modify the standard order flow. The new flow will now look like this:
1. Payment Service Provider authorizes the payment.
2. An order is placed in reaction to the authorized payment.
3. The order is put on hold pending fraud check. Below you can see how it looks like in Centra’s administration panel:
4. The Partner Integration is notified that an order is awaiting fraud check.
5. The Partner Integration performs request to the external Fraud Check Solution.
6. The Partner Integration updates the order according to the result of the fraud check.
Payment plugins that work with the Fraud Prevention plugin#
Currently there are two PSPs that can be used in conjunction with the External Fraud Prevention plugin:
- Adyen drop-in
- Klarna Payments
Order flow slightly differs depending on the PSP that processed the payment for the order.
Adyen drop-in
- Waiting for Fraud Check flag is assigned only after Waiting for Payment flag is cleared.
Klarna Payments
- Waiting for Fraud Check flag is assigned immediately after order placement.
How to integrate a Fraud Prevention Solution with Centra#
Step 1. Set up the Fraud Prevention plugin
Firstly, you will have to add the External Fraud Prevention plugin to your store. Below are the available settings that the plugin exposes:
-
Connector - defines how the store communicates with the Fraud Check Prevention solution. Currently the only available option is Custom.
-
Connector url - available only for the Custom connector. It specifies the URL to which the store will send requests regarding Fraud Check Prevention.
Step 2. Handle the Custom connector notifications
This part handles communicating to your custom built integration that an order is awaiting fraud check. It does so through the URL provided in the plugin settings. Note that:
-
The connector notifies the custom integration about: orders awaiting fraud check, failed authorization payments.
-
The notifications to the custom integration will contain the data about the order, including customer and payment details. Every type of request will contain the same structure of the body.
Example request:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
{
"billingAddress": {
"email": "email@example.com",
"firstName": "Sven",
"lastName": "Nilsson",
"company": "Company name",
"address1": "Roslagsgatan 10",
"address2": "",
"zipCode": "113 51",
"city": "Stockholm",
"state": "Stockholm",
"country": "sv_SV",
"countryName": "Sweden",
"phoneNumber": "+XX XXX XXX XXX",
"vatNumber": "SE999999999999"
},
"shippingAddress": {
"email": "email@example.com",
"firstName": "Sven",
"lastName": "Nilsson",
"company": "Company name",
"address1": "Roslagsgatan 10",
"address2": "",
"zipCode": "113 51",
"city": "Stockholm",
"state": "Stockholm",
"country": "sv_SV",
"countryName": "Sweden",
"phoneNumber": "+XX XXX XXX XXX"
},
"order": {
"order": "#ORDER_REF"
},
"orderLines": [
{
"sku": "SKU_CODE",
"brand": "Brand name",
"name": "T-shirt",
"quantity": 1,
"totalPrice": 10000
}
],
"notificationType": 'orderWaitingForFraudCheck'|'failedPaymentAttempt',
"paymentDetails": {
"pspReference": "reference",
"pspIdentifier": 'klarna-payments'|'adyen_drop_in',
"pspResponse": [
'response data from the payment service provider'
]
},
// sent only when provided by front end
"device_details": {
"browser_language": "sv-sv",
"ip_address": "127.0.0.1",
"user_agent": "Mozilla\/5.0 (Macintosh; Intel Mac OS X 14.4; rv:123.0) Gecko\/20100101 Firefox\/123.0"
}
}
In case more data is required, it can be fetched via the Integration API (more on that later).
Step 3. Update the order through the Partner Integration
This is the part where the actual fraud check result is being handled. Any communication with Centra store should be conducted via the Centra Integration API. Below are the steps that need to be taken in order to process the order awaiting fraud check.
1. Any additional data required to perform the check needs to be fetched via the orders query.
Query structure:
1
2
3
4
5
6
7
8
9
query orders {
orders(where: { id: "1015bd448795c9df7f7bf369ddef09d3" }) {
id
isOnHold
status
orderHoldReason
// any additional fields you may require
}
}
Example response:
1
2
3
4
5
6
7
8
9
10
11
12
{
"data": {
"orders": [
{
"id": "f2024bfb7a1de1ab5dcc2e3bb99556d0",
"isOnHold": false,
"status": "DELETED",
"orderHoldReason": ["WAITING_FOR_FRAUD_CHECK"]
}
]
}
}
2. To find all orders awaiting fraud check, the above query has to contain the orderHoldReason field with the value of WAITING_FOR_FRAUD_CHECK.
Query structure:
1
2
3
4
5
6
7
8
query orders {
orders(where: { orderHoldReason: [WAITING_FOR_FRAUD_CHECK] }) {
id
isOnHold
status
orderHoldReason
}
}
Example response:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
"data": {
"orders": [
{
"id": "f2024bfb7a1de1ab5dcc2e3bb99556d0",
"isOnHold": false,
"status": "DELETED",
"orderHoldReason": ["WAITING_FOR_FRAUD_CHECK"]
},
{
"id": "1015bd448795c9df7f7bf369ddef09d3",
"isOnHold": true,
"status": "PENDING",
"orderHoldReason": ["WAITING_FOR_FRAUD_CHECK"]
},
]
}
}
3. All the necessary external calls to the fraud prevention solution should be performed using the previously acquired data.
4. If the order is deemed as valid, the resumeDirectToConsumerOrder mutation should be called.
Example request:
1
2
3
4
5
6
7
mutation resumeDirectToConsumerOrder(
resumeOrder(order: { id: "1015bd448795c9df7f7bf369ddef09d3" }) {
order,
userErrors,
userWarnings
}
)
Example response:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"data": {
"resumeOrder": {
"order": {
"id": "1015bd448795c9df7f7bf369ddef09d3",
"status": "PENDING",
// remaining fields
},
// Any errors or warnings that may have occured
"userErrors": ["message": "Error message", "path": ["field"]],
"userWarnings": ["message": "Warning message", "path": ["field"]]
}
}
}
If the order is deemed as fraudulent, the cancelDirectToConsumerOrder mutation should be called. In this case, the addition cancelReason needs to be provided with the value of FRAUD_CHECK_REJECTED
Example request:
1
2
3
4
5
6
7
8
9
10
mutation cancelDirectToConsumerOrder(
cancelOrder(
order: { id: "1015bd448795c9df7f7bf369ddef09d3" },
input: { cancelReason: "FRAUD_CHECK_REJECTED" }
) {
order,
userErrors,
userWarnings
}
)
Example response:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"data": {
"cancelOrder": {
"order": {
"id": "1015bd448795c9df7f7bf369ddef09d3",
"status": "CANCELLED",
// remaining fields
},
// Any errors or warnings that may have occured
"userErrors": ["message": "Error message", "path": ["field"]],
"userWarnings": ["message": "Warning message", "path": ["field"]]
}
}
}
If the order has been resumed, it can now be processed further. This is how the order history will look like in the Centra’s administration panel: