Webhooks

Webhooks allow you to receive real-time notifications when events occur in Baback. When a returnRequest is created, updated, or changes status, we'll send a POST request to your configured webhook endpoint with the event data.

Webhook Events

Currently, we support the following webhook events:

  • returnRequest:returnRequest:create - Triggered when a new return request is created
  • returnRequest:returnRequest:cancel - Triggered when a return request is cancelled
  • returnRequest:returnRequest:approve - Triggered when a return request is pre-evaluated
  • returnRequest:returnRequest:update - Triggered when a return request is updated
  • returnRequest:merchant:approve - Triggered when a merchant accepts items in a return request
  • returnRequest:logistician:approve - Triggered when a logistician accepts items in a return request
  • returnRequest:discount:create - Triggered when a discount is created for a return request

Webhook Payload Structure

All webhook payloads follow the same structure, containing:

  • action - The type of event that occurred
  • secret - Your webhook secret for verification (if configured)
  • returnRequest - The complete return request object

Example Webhook Payload

Here's an example of what you'll receive when a return request is created:

{
  "data": {
    "action": "returnRequest:returnRequest:create",
    "secret": "your-webhook-secret",
    "returnRequest": {
      "billingAddress": {
        "address1": "123 Main Street",
        "address2": null,
        "city": "New York",
        "country": "United States",
        "countryCode": "US",
        "firstName": "John",
        "lastName": "Doe",
        "phone": "+1234567890",
        "province": "New York",
        "provinceCode": "NY",
        "zip": "10001"
      },
      "currency": {
        "conversionRateCustomerOnShop": 1,
        "customerCurrency": "USD",
        "shopCurrency": "USD"
      },
      "customer": {
        "email": "customer@example.com",
        "firstName": "John",
        "id": "1234567890123",
        "lastName": "Doe",
        "phone": "+1234567890",
        "giftCodeId": null,
        "tags": ["vip_customer"],
        "metafields": [],
        "customerSegment": null
      },
      "exchange": {
        "draftOrderId": "",
        "newProductForExchangeCredit": []
      },
      "financialInformations": {
        "discount": {
          "amount": 0,
          "codes": [],
          "currency": "USD",
          "presentmentAmount": 0
        },
        "discountBonus": {
          "bonus": {
            "amount": 0,
            "type": "percentage",
            "currency": "USD"
          },
          "done": false
        },
        "exchangeCredit": {
          "amount": 0,
          "currency": "USD",
          "presentmentAmount": 0
        },
        "initialShippingRefunded": {
          "amount": 0,
          "currency": "USD",
          "done": false,
          "method": "refund",
          "presentmentAmount": 0,
          "sourceAmount": 0
        },
        "originalDiscount": {
          "amount": 0,
          "currency": "USD",
          "discountCodes": [],
          "done": false,
          "method": "refund",
          "presentmentAmount": 0,
          "sourceAmount": 0
        },
        "rebuy": {
          "amount": 0,
          "currency": "USD",
          "presentmentAmount": 0
        },
        "refund": {
          "amount": 0,
          "currency": "USD",
          "presentmentAmount": 150
        },
        "reshipping": {
          "amount": 0,
          "currency": "USD",
          "presentmentAmount": 0
        },
        "returnShippingPaid": {
          "amount": 0,
          "currency": "USD",
          "done": false,
          "method": "refund",
          "presentmentAmount": 0
        },
        "taxes": [],
        "totalOrderPrice": {
          "amount": 299,
          "currency": "USD"
        },
        "rebuyRefund": {
          "done": false,
          "method": "refund",
          "presentmentAmount": 0,
          "amount": 0,
          "currency": "USD",
          "codes": []
        },
        "intentId": ""
      },
      "lineItems": [
        {
          "bodyHtml": "",
          "comment": null,
          "compareAtPrice": "0",
          "countryOfOrigin": "US",
          "customAttributes": [],
          "customerImages": [],
          "discountsAllocated": [],
          "harmonizedSystemCode": "62111200",
          "image": "https://cdn.shopify.com/s/files/1/example/product-image.jpg",
          "lineItemId": "12345678901234",
          "logisticianInformations": [],
          "merchantInformations": [],
          "newVariant": null,
          "originLocation": {
            "address1": "456 Warehouse Ave",
            "address2": "Suite 100",
            "city": "Los Angeles",
            "country": "United States",
            "countryCode": "US",
            "countryName": "United States",
            "provinceCode": "CA",
            "zip": "90210"
          },
          "paidPrice": "49.99",
          "unitTaxes": [],
          "price": "49.99",
          "product": {
            "metafields": [
              {
                "key": "material",
                "value": "Cotton",
                "type": null,
                "namespace": null
              },
              {
                "key": "care_instructions",
                "value": "Machine wash cold, tumble dry low",
                "type": null,
                "namespace": null
              }
            ],
            "productId": "1234567890123"
          },
          "quantity": 1,
          "quantityBought": 1,
          "reasonId": "abc123def456",
          "resolution": "refund",
          "returnable": true,
          "sku": "SAMPLE-SKU-001",
          "title": "Sample Product Name",
          "variant": {
            "barcode": "1234567890123",
            "metafields": [
              {
                "key": "size",
                "value": "Medium",
                "type": null,
                "namespace": null
              }
            ],
            "option1": "Medium",
            "option2": null,
            "option3": null,
            "title": "Medium",
            "variantId": "12345678901234"
          },
          "weight": 0.5
        }
      ],
      "logs": [
        {
          "author": null,
          "comment": null,
          "date": 1672531200000,
          "emailSent": null,
          "errorType": null,
          "errorDetail": null,
          "id": "log-id-12345",
          "newStatus": "created",
          "params": {
            "userId": "user123456"
          },
          "status": null,
          "type": "updateStatus"
        }
      ],
      "metafields": [],
      "previousShippingLine": {
        "carrierIdentifier": null,
        "code": "Standard Shipping",
        "isPickingPoint": false,
        "title": "Standard Shipping"
      },
      "shippingAddress": {
        "address1": "123 Main Street",
        "address2": "",
        "city": "New York",
        "country": "United States",
        "countryCode": "US",
        "countryName": null,
        "firstName": "John",
        "lastName": "Doe",
        "phone": "+1234567890",
        "province": "New York",
        "provinceCode": "NY",
        "zip": "10001",
        "companyName": null,
        "email": "customer@example.com"
      },
      "shippingInfo": {
        "carrier": "ups-ground",
        "hasLogisticLabel": false,
        "labelUrl": "https://api.baback.co/public/labels/sample-label-id",
        "logisticCode": "#EXAMPLE-001-R1",
        "pickingTiming": {
          "instruction": "",
          "pickupTimeEnd": 0,
          "pickupTimeStart": 0
        },
        "locationId": "location123",
        "returnStoreId": "",
        "trackingCode": "1Z123456789012345"
      },
      "status": {
        "created": {
          "done": true,
          "doneAt": 1672531200000,
          "reason": null,
          "status": null
        },
        "approved": {
          "done": true,
          "doneAt": 1672531260000,
          "reason": null,
          "status": null
        },
        "waiting": {
          "done": true,
          "doneAt": 1672531260000,
          "reason": null,
          "status": null
        },
        "shipping": {
          "done": false,
          "doneAt": -1,
          "reason": null,
          "status": null
        },
        "shipped": {
          "done": false,
          "doneAt": -1,
          "reason": null,
          "status": null
        },
        "partiallyTreatedLogistician": {
          "done": false,
          "doneAt": -1,
          "reason": null,
          "status": null
        },
        "treatedLogistician": {
          "done": false,
          "doneAt": -1,
          "reason": null,
          "status": null
        },
        "partiallyTreatedMerchant": {
          "done": false,
          "doneAt": -1,
          "reason": null,
          "status": null
        },
        "treatedMerchant": {
          "done": false,
          "doneAt": -1,
          "reason": null,
          "status": null
        },
        "cancelled": {
          "done": false,
          "doneAt": -1,
          "reason": null,
          "status": null
        },
        "error": {
          "done": false,
          "doneAt": -1,
          "reason": null,
          "status": null
        },
        "resolved": {
          "done": false,
          "doneAt": -1,
          "reason": null,
          "status": null
        }
      },
      "transport": {
        "pickingSlot": "",
        "type": "carrier"
      },
      "customAttributes": [],
      "integrations": [],
      "notifications": {
        "consumerEnabled": true
      },
      "id": "return-request-12345",
      "assignedUsers": [],
      "createdAt": 1672531200000,
      "lang": "en-US",
      "orderId": "9876543210987",
      "orderName": "#EXAMPLE-001",
      "orderedAt": 1672444800000,
      "orderShippedAt": 1672488000000,
      "shopId": "shop123456789",
      "shopifyReturnId": "shopify-return-123",
      "updatedAt": 1672531200000,
      "rebuyRemainingCreditMethod": "refund",
      "_id": "return-request-12345"
    }
  }
}

Webhook Security

To ensure the authenticity of webhook requests, you can:

  1. Use HTTPS endpoints - Always use HTTPS URLs for your webhook endpoints
  2. Verify the webhook secret - If you configure a webhook secret, verify it matches the secret field in the payload
  3. Validate the payload structure - Ensure the incoming payload matches the expected format

Handling Webhooks

Your webhook endpoint should:

  1. Return a 200 status code to acknowledge receipt
  2. Process the webhook asynchronously to avoid timeouts
  3. Be idempotent - Handle duplicate webhook deliveries gracefully
  4. Validate the payload before processing

Example webhook handler:

app.post('/webhook/baback', (req, res) => {
  const { action, returnRequest, secret } = req.body.data;
  
  // Verify webhook secret (if configured)
  if (process.env.WEBHOOK_SECRET && secret !== process.env.WEBHOOK_SECRET) {
    return res.status(401).send('Unauthorized');
  }
  
  // Handle different event types
  switch (action) {
    case 'returnRequest:returnRequest:create':
      handleReturnRequestCreated(returnRequest);
      break;
    case 'returnRequest:returnRequest:cancel':
      handleReturnRequestCancelled(returnRequest);
      break;
    case 'returnRequest:returnRequest:approve':
      handleReturnRequestApproved(returnRequest);
      break;
    case 'returnRequest:returnRequest:update':
      handleReturnRequestUpdated(returnRequest);
      break;
    case 'returnRequest:merchant:approve':
      handleMerchantApproval(returnRequest);
      break;
    case 'returnRequest:logistician:approve':
      handleLogisticianApproval(returnRequest);
      break;
    case 'returnRequest:discount:create':
      handleDiscountCreated(returnRequest);
      break;
    default:
      console.log('Unknown webhook event:', action);
  }
  
  res.status(200).send('OK');
});