Connect your shipping or payment service with the SEOshop platform.

Shipping service Payment service Give it a spin

How to get started

POST /external_services.json

Your payload

{
  "externalService": {
    "type": "shipment",
    "name": "SEOshop Shipments",
    "urlEndpoint": "https://api.yourdomain.com/",
    "rateEstimate": true,
    "isActive": true
  }
}

PHP sample

$api = new WebshopappApiClient(...);

$api->external_services->create([
    'type'          => 'shipment',
    'name'          => 'SEOshop Shipments',
    'urlEndpoint'   => 'https://api.yourdomain.com/',
    'rateEstimate'  => true,
    'isActive'      => true
]);

We will call your endpoint during the checkout process. First you'll have to send us your endpoint information. Do this by calling our /external_services.json endpoint.

A external service can either be a shipment or a payment service. If you'd like to offer both simply create two external services, each with a different type. The endpoint must be accessible over HTTPS. The rateEstimate field is only applicable for shipment services. Read more about that here.

Please note that a external service is unique per shop. So for every shop that wants to use your service you'll have to create a new external service.

Our PHP client supports the external service resource and makes it super easy to use. Learn more about the PHP client.

A more detailed tutorial is available right here.


How we fetch shipment methods

Live example POST /shipment_methods

Our payload

{
  "rate_estimate": false,
  "shop": {
    "id": 1,
    "language": "nl",
    "currency": "eur"
  },
  "customer": {
    "firstname": "Menno",
    "middlename": false,
    "lastname": "Wolvers",
    "phone": false,
    "mobile": false,
    "type": "private",
    "company": ""
  },
  "billing_address": {
    "name": "Menno Wolvers",
    "company": "",
    "address1": "Keizersgracht",
    "address2": null,
    "number": 313,
    "extension": "",
    "zipcode": "1016 EE",
    "city": "Amsterdam",
    "region": false,
    "country": "nl"
  },
  "shipping_address": {
    "name": "Menno Wolvers",
    "company": "",
    "address1": "Keizersgracht",
    "address2": null,
    "number": 313,
    "extension": "",
    "zipcode": "1016 EE",
    "city": "Amsterdam",
    "region": false,
    "country": "nl"
  },
  "quote": {
    "id": 1486,
    "price_incl": "36.58",
    "price_excl": "30.23",
    "vat_shifted": false,
    "weight": 110,
    "volume": 200,
    "colli": 2,
    "products": [{
      "product_id": 10546,
      "variant_id": 17706,
      "title": "Lamswollen sjaal",
      "fulltitle": "Lamswollen sjaal",
      "variant": null,
      "description": "Een fijngebreide sjaal van lamswolmix met blokstrepen. Afmeting 35x185 cm.",
      "price_incl": 36.58,
      "price_excl": 30.23,
      "tax_rate": 0.21,
      "quantity": 2,
      "article_code": null,
      "ean": null,
      "sku": "AC0002",
      "size_x": 10,
      "size_y": 10,
      "size_z": 10,
      "weight": 110,
      "volume": 200,
      "colli": 2,
      "stock_available": true
    }]
  }
}

Your response

{
  "shipment_methods": [
    {
      "title": "1 hour delivery",
      "description": "We'll deliver your package within one hour, inside Amsterdam.",
      "price_incl": 6.05,
      "price_excl": 5.00,
      "tax_rate": 0.21,
      "is_pickup": false,
      "is_servicepoint": false,
      "is_cash_on_delivery": false
    },


    {
      "title": "1 day delivery",
      "description": "We'll deliver your package tomorrow.",
      "price_incl": 0,
      "tax_rate": 0.21,
      "is_pickup": false,
      "is_servicepoint": false,
      "is_cash_on_delivery": false
    }
  ]
}

When a customer enters the checkout, we'll send a POST request to your endpoint to fetch the shipment methods. The payload contains all relevant information regarding the current checkout including customer and product data.

Now you'll respond with a valid json document that contains a field shipment_methods. This field is an array with all available shipment methods.

There are two types of payloads, depending on the rate_estimate field. When this field states true, we do not have much customer information yet and are simply asking for a fare estimate of the shipping methods. This request is performed in the shopping cart. When the field states false, we will send you much more information.

Read more on the rate estimate call.

Unlike with the payment service integration, we will not send you a call when one of your shipment methods has been chosen. Instead you can hook into the order creation event (See webhooks) to see if your service has been chosen.


How we fetch payment methods

Live example POST /payment_methods

Our payload

{
  "shop": {
    "id": 1,
    "language": "nl",
    "currency": "eur"
  },
  "customer": {
    "firstname": "Menno",
    "middlename": "",
    "lastname": "Wolvers",
    "phone": "",
    "mobile": "",
    "type": "private",
    "company": false
  },
  "billing_address": {
    "name": "Menno Wolvers",
    "company": false,
    "address1": "Keizersgracht",
    "address2": "",
    "number": 313,
    "extension": "",
    "zipcode": "1016 EE",
    "city": "Amsterdam",
    "region": "",
    "country": "nl"
  },
  "shipping_address": {
    "name": "Menno Wolvers",
    "company": null,
    "address1": "Keizersgracht",
    "address2": "",
    "number": 313,
    "extension": "",
    "zipcode": "1016 EE",
    "city": "Amsterdam",
    "region": "",
    "country": "nl"
  },
  "quote": {
    "id": 1486,
    "price_incl": 55.43,
    "price_excl": 45.81,
    "vat_shifted": false,
    "weight": 165,
    "volume": 300,
    "colli": 3,
    "products": [{
      "product_id": 10546,
      "variant_id": 17706,
      "title": "Lamswollen sjaal",
      "fulltitle": "Lamswollen sjaal",
      "variant": "",
      "price_incl": 49.38,
      "price_excl": 40.81,
      "tax_rate": 0.21,
      "quantity": 3,
      "article_code": "",
      "ean": "",
      "sku": "AC0002",
      "size_x": 10,
      "size_y": 10,
      "size_z": 10,
      "weight": 55,
      "volume": 100,
      "colli": 1
    }]
  }
}

Your response

{
  "payment_methods": [
    {
      "id": 1,
      "title": "Mastercard",
      "price_incl":6.05,
      "price_excl": 5.00,
      "tax_rate": 0.21,
      "icon": "mastercard"
    },
    {
      "id": 2,
      "title": "Visa",
      "price_incl":6.05,
      "price_excl": 5.00,
      "tax_rate": 0.21,
      "icon": "visa"
    },
    {
      "id": 3,
      "title": "Pay after delivery",
      "price_incl":6.05,
      "price_excl": 5.00,
      "tax_rate": 0.21,
      "icon": "https://yourdomain.com/icon-pay-after-delivery.png"
    }
  ]
}

When a customer reaches the payment method step in the checkout, we'll call your endpoint to fetch the available payment methods. The request contains an extensive payload with all relevant information about the customer, the products he is buying, and the shipment method that was chosen. Based on this information you can decide which payment methods should be available.

Now you'll respond with a valid json document that contains a field payment_methods. This field is an array with all available payment methods. Each payment method must consist of a unique identifier, a title, an icon, and a price.

When one of your payment methods has been chosen and the checkout is finished, we'll call your endpoint again.

Read more about the payment process.


The payment process

POST /payment

Our payload

{
  "order":{
    "id":2996178,
    "number":"01918",
    "price_incl":29.3400,
    "price_excl":25.1200,
    "price_tax":4.2200,
    "currency":"eur"
  },
  "customer":{
    "id":103,
    "email":"info@seoshop.com",
    "gender":"male",
    "firstname":"Menno",
    "middlename":"",
    "lastname":"Wolvers",
    "fulllastname":"Wolvers",
    "fullname":"Menno Wolvers",
    "phone":"",
    "mobile":"",
    "birthdate":"685144800",
    "type":"private",
    "company":"SEOshop",
    "cocnumber":false,
    "vatnumber":false
  },
  "payment_method":{
    "id":"my-awesome-app",
    "method":"pay-after-delivery",
    "title":"Pay After Delivery - MyAwesomeApp",
    "data":{
      "gender":"male",
      "phone":"02012345678",
      "birthdate_d":"18",
      "birthdate_m":"9",
      "birthdate_y":"1991",
      "terms":"1",
      "method":"ideal",
      "birthdate":"1991-9-18",
      "app_id":"72"
    }
  },
  "redirect_url":"http://domain.webshopapp.com/nl/payment/my-awesome-app/success/?order_id=2996178",
  "webhook_url":"https://domain.webshopapp.com/nl/payment/my-awesome-app/notify/?order_id=2996178"
}

Your response

{
  "payment_url": "http://yourdomain.com/pay/2996178"
}

If the customer has selected one of your payment methods, we will call your endpoint when he confirms the purchase. The request contains all relevant information about the customer and his order.

Based on the payment method the customer might need to pay on your platform. Therefore you can reply with a payment_url in the response. If this is present we'll redirect the customer to this url. If you do not provide a payment url we will send the customer to the regular thank you page and the order has not yet been paid.

In the initial request we have send you two urls. When the customer is done on your platform you send him to the provided redirect_url. Some payments take longer to process, in these cases you can notify us about the payment status through the webook_url as provided in the request.


Verify the payment status

Live example GET /payment/{order_id}

Your response

{
  "status": "paid"
}

After you redirect the customer back to the redirect_url, we'll have to verify the status of the payment. We do this by performing a GET request to your endpoint based on the order id. In the response you can reply with a status, that can either be paid, unpaid, or cancelled.

When the payment has been cancelled we give the customer the option to choose another payment method. At this point we'll call your endpoint again to fetch the available payment methods and the cycle may repeat itself.

If the order has been paid or unpaid we send the customer to the thank you page. The order has now been completed. In this case we see unpaid as may-be-paid-later. If this is not the case then send us the status cancelled so we can let the customer pay again through another payment method.


Give it a spin

We have set up a demo shop with this external service integrated. The methods as seen in the request /shipment_methods and /payment_methods will show up in the checkout.

Try ordering something with the SEOcoin payment method and see how we redirect the user, and back.

Give it a spin Check the code