Refund Abuse Integration

Requesting Recommendations

On this page:

Recommendations at refund

To request a recommendation when a customer asks for a refund, send a request to our Refund endpoint using the Refund Request checkpoint.

To use the Refund Request checkpoint add score=refundRequest as a query parameter to the URL.

Set refund.status to OPEN.

If the refund is for specific items, send these in the refund.items array. Provide refundReason each item. If the refund is not for specific items, set the refund.refundReason value instead.

We strongly recommend sending all fields marked in the Refund endpoint API reference as important. The more fields you can populate the better our recommendation.

An example request is shown below:

POST https://api.ravelin.com/v2/refund?score=refundRequest HTTP/1.1
Authorization: token ...
Content-Type: application/json

{
  "timestamp": 1512828988826,
  "customer": {
    "customerId": "abc-123-ZYZ"
  },
  "order": {
    "orderId": "abcde12345-ZXY"
  },
  "refund": {
    "refundId": "abc-123-GDFS",
    "refundRequestTime": 1636629706000,
    "status": "OPEN",
    "initiatedBy": "CUSTOMER",
    "type": "REFUND",
    "claim": "FULL",
    "policy": "TERMS_AND_CONDITIONS",
    "amount": 1000,
    "currency": "GBP",
    "nonRefundableAmount": 250,
    "refundIssuedTo": [
      "ORIGINAL_PAYMENT_METHOD",
      "GIFT_CARD"
    ],
    "items": [
      {
        "name": "Midi Dress",
        "quantity": 1,
        "price": 1000,
        "currency": "GBP",
        "sku": "1234AAB",
        "category": "Clothing",
        "subcategory": "Dresses",
        "brand": "Trendy Threads",
        "refundReason": "ITEM_NOT_RECEIVED"
      }
    ]
  },
  "device": {
    "deviceId": "df020f51-5ebb-4901-82cf-96299225754b"
  }
}

An example response is shown below.

{
  "status": 200,
  "timestamp": 1637933719,
  "data": {
    "customerId": "abc-123-ZYZ",
    "action": "PREVENT",
    "source": "RULE",
    "rules": {
      "triggered": [
        {
          "triggered": true,
          "description": "Customer is a serial complainer",
          "state": "active",
          "action": "PREVENT"
        }
      ]
    }
  }
}

The data.action field in the response contains our recommendation.

You should either allow or prevent the refund depending on the data.action value.

The possible values are:

Action What it means
ALLOW We are confident this is a legitimate refund request. Issue the refund to the customer.
PREVENT We are confident this is refund abuse. Do not issue the refund to the customer

It is also possible to configure additional action values, such as MANUAL_REVIEW, which can be used to mark suspicious customers for investigation by your fraud team. We will work with you directly if there are additional action values you want to implement.

The data.source field in the response will tell you what generated the refund recommendation. This can be used for further investigation and analysis.

Recommendations at checkout

To request a refund abuse recommendation when a customer attempts to place an order at checkout, send a request to our Checkout endpoint using the Checkout Pre-auth checkpoint.

If you are integrated with Payment Fraud you may already be sending a Checkout request. Our recommendation at checkout will take into account all the types of fraud you are integrated to prevent.

An example request is shown below:

POST https://api.ravelin.com/v2/checkout?score=checkoutPreAuth HTTP/1.1
Authorization: token ...
Content-Type: application/json

{
  "timestamp": 1512828988826,
  "customer": {
    "customerId": "abc-123-ZYZ",
    "registrationTime": 1512828988826,
    "email": "jsmith123@example.com",
    "name": "John Smith",
    "telephone": "+447000000001",
    "telephoneCountry": "GBR"
  },
  "device": {
    "deviceId": "65fc5ac0-2ba3-4a3b-aa5e-f5a77b845260",
    "type": "phone",
    "manufacturer": "google",
    "model": "Pixel XL",
    "os": "android",
    "language": "en-US",
    "ipAddress": "81.152.92.84"
  },
  "order": {
    "orderId": "abcde12345-ZXY",
    "creationTime": 1512828988826,
    "price": 1500,
    "currency": "GBP",
    "market": "emea",
    "country": "GBR",
    "marketCity": "london",
    "items": [
      {
        "sku": "0001",
        "name": "Margherita Pizza",
        "quantity": 1,
        "price": 1500
      }
    ],
    "status": {
      "stage": "pending",
      "actor": "merchant"
    }
  },
  "paymentMethods": [
    {
      "paymentMethodId": "pm-abc123",
      "instrumentId": "fp_abc123",
      "methodType": "card",
      "scheme": "visa",
      "cardBin": "535522",
      "cardLastFour": "0001",
      "expiryMonth": 7,
      "expiryYear": 2020,
      "nameOnCard": "John Smith",
      "billingAddress": {
        "addresseeName": "John Smith",
        "street1": "123 High Street",
        "city": "London",
        "country": "GBR",
        "postalCode": "E1 1AA"
      }
    }
  ],
  "transactions": [
    {
      "transactionId": "123-abc-XYZ",
      "paymentMethodId": "pm-abc123",
      "time": 1512828988826,
      "amount": 1000,
      "currency": "GBP",
      "type": "auth",
      "gateway": "example-gateway"
    }
  ]
}

An example response is shown below:

{
  "status": 200,
  "timestamp": 1652103786,
  "success": "true",
  "data": {
    "customerId": "abc-123-ZYZ",
    "action": "ALLOW",
    "score": 2,
    "source": "RAVELIN",
    "scoreId": "8f7c4a67-c944-4ae7-7a76-d9a7a3942dd5"
  }
}

The data.action field in the response contains our recommendation, you should use this to determine how you handle the order. The table below explains the actions.

Action Action to take
ALLOW It is unlikely the order will lead to refund abuse. Allow the order to proceed.
REVIEW The order may lead to refund abuse. Take extra verification steps for the order.
3DS_AUTHENTICATE The order may lead to refund abuse. We suggest verifying the customer using 3D Secure.
MANUAL_REVIEW The order may lead to refund abuse. We suggest verifying the order by doing a manual review.
PREVENT It is likely the order will lead to refund abuse. Prevent the order.

You can also configure additional custom actions which suit your business. Please speak to our integration team to configure these.

Refund updates

You should send us the outcome of all customer refund requests, regardless of whether you requested a refund recommendation. This allows us to learn the behaviour of your customers and make better refund recommendations.

Send the refund outcome to the Refund endpoint.

Since you will have already issued or rejected the refund, do not use the Refund Request checkpoint.

If you issued the refund, set the following fields:

  • refund.status: "COMPLETED"
  • refund.refundIssuedTime
  • order.status.stage: refunded
  • transaction.type: refund

If you did not issue the refund, set the following fields:

  • refund.status: "DECLINED"
  • refund.declineReason

An example request for a completed refund is shown below:

POST https://api.ravelin.com/v2/refund HTTP/1.1
Authorization: token ...
Content-Type: application/json

{
  "timestamp": 1512828988826,
  "customer": {
    "customerId": "abc-123-ZYZ"
  },
  "order": {
    "orderId": "abcde12345-ZXY",
    "status": {
      "stage": "refunded"
    }
  },
  "refund": {
    "refundId": "abc-123-GDFS",
    "refundRequestTime": 1636629706000,
    "refundIssuedTime": 1636629706000,
    "status": "COMPLETED",
    "initiatedBy": "CUSTOMER",
    "type": "REFUND",
    "claim": "FULL",
    "policy": "TERMS_AND_CONDITIONS",
    "amount": 7000,
    "currency": "GBP",
    "refundIssuedTo": [
      "ORIGINAL_PAYMENT_METHOD",
      "GIFT_CARD"
    ],
    "items": [
      {
        "name": "Heart Gold Necklace",
        "quantity": 1,
        "price": 7000,
        "currency": "GBP",
        "sku": "345682KGP",
        "category": "Accessories",
        "subcategory": "Jewellery",
        "brand": "Trendy Threads",
        "refundReason": "CUSTOMER_INCORRECT_ITEM"
      }
    ]
  },
  "transactions": [
    {
      "transactionId": "pi_3Jd",
      "paymentMethodId": "card_1Ijim5Bvd0CnXcVWpZz66Idb",
      "gateway": "stripe",
      "gatewayReference": "65645tfghdhgd",
      "amount": 7000,
      "currency": "GBP",
      "type": "refund",
      "success": true,
      "time": 1512828988826
    }
  ]
}

If you previously requested a refund recommendation you do not need to send all the details of the refund again. You can just send refund.refundId and the fields describing the outcome of the refund request.

An example request for a completed refund, using refundId, is shown below:

POST https://api.ravelin.com/v2/refund HTTP/1.1
Authorization: token ...
Content-Type: application/json

{
  "timestamp": 1512828988826,
  "customer": {
    "customerId": "abc-123-ZYZ"
  },
  "order": {
    "orderId": "abcde12345-ZXY",
    "status": {
      "stage": "refunded"
    }
  },
  "refund": {
    "refundId": "abc-123-GDFS",
    "refundIssuedTime": 1512828988826,
    "status": "COMPLETED"
  },
  "transactions": [
    {
      "transactionId": "pi_3Jd",
      "paymentMethodId": "card_1Ijim5Bvd0CnXcVWpZz66Idb",
      "gateway": "stripe",
      "gatewayReference": "65645tfghdhgd",
      "amount": 700,
      "currency": "GBP",
      "type": "refund",
      "success": true,
      "time": 1512828988826
    }
  ]
}

An example request for a declined refund, using refundId, is shown below:

POST https://api.ravelin.com/v2/refund HTTP/1.1
Authorization: token ...
Content-Type: application/json

{
  "timestamp": 1512828988826,
  "customer": {
    "customerId": "abc-123-ZYZ"
  },
  "order": {
    "orderId": "abcde12345-ZXY"
  },
  "refund": {
    "refundId": "abc-123-ZYZ",
    "status": "DECLINED",
    "declineReason": "RAVELIN"
  }
}

Next steps

Test your refund abuse integration

Feedback