Introduction
Welcome to the OderoPay API! You can use our API to access Odero API endpoints, which can get information on various payments, cards, recurrings, deposits, refunds in our database.
We have language bindings in Shell, Php, Python, and Nodejs! You can view code examples in the dark area to the right, and you can switch the programming language of the examples with the tabs in the top right.
Installation
You can access our SDK's directly on our Github Page.
PHP
composer require oderopay/odero-php
Minimum Requirements;
- PHP 7.2 or later
- curl
- json
- mbstring
Authentication
To authorize, use this code:
//Authentication is already handled by SDK
$config = new \Oderopay\OderoConfig('My Store Name', '{merchant-id}', '{merchant-token}', \Oderopay\OderoConfig::ENV_STG);
//Just initialize the Odero Client with given config.
$oderopay = new \Oderopay\OderoClient($config);
To be authenticated, you need to send X-MERCHANT-SIGNATURE
value in header.
The header X-MERCHANT-SIGNATURE is generated by each merchant when a new request is initialized to API Endpoints.
Items used in header generation:
- Merchant ID;
- Payload (encoded as json);
- Merchant API Token.
Used Algorithm: sha256
How is the header generated?
Card Operations
Store Card
$billingAddress = new \Oderopay\Model\Address\BillingAddress();
$billingAddress
->setAddress('185 Berry St #550, San Francisco, CA 94107, USA')
->setCity('San Francisco')
->setCountry('USA');
$deliveryAddress = new \Oderopay\Model\Address\DeliveryAddress();
$deliveryAddress
->setAddress('185 Berry St #550, San Francisco, CA 94107, USA')
->setCity('San Francisco')
->setCountry('USA')
->setDeliveryType('Courier');
$customer = new \Oderopay\Model\Payment\Customer();
$customer
->setEmail('customer@email.com')
->setPhoneNumber(' +19159969739')
->setDeliveryInformation($deliveryAddress)
->setBillingInformation($billingAddress);
$card = new \Oderopay\Model\Card\SaveCard();
$card->setCustomer($customer);
$card->setCurrency('RON');
$card->setReturnUrl('https://my-store.com/');
$cardResponse = $oderopay->cards->create($card); //CardSaveResponse
if($cardResponse->isSuccess()){
return http_redirect($cardResponse->data['url'])
}else{
log($cardResponse->message);
}
{
"merchantId": "uuid",
"returnUrl": "string",
"currency": "string",
"customer": {
"email": "string",
"phoneNumber": "string",
"deliveryInformation": {
"deliveryType": "string",
"country": "string",
"city": "string",
"address": "string"
},
"billingInformation": {
"country": "string",
"city": "string",
"address": "string"
}
}
}
The above command returns an object like this:
{
"operationId": "uuid",
"message": "string",
"data": {
"paymentId": "uuid",
"url": "string"
}
}
This endpoint creates a card save request and returns the url of hosted card storage page if success.
HTTP Request
POST /api/cards
Body
Parameter | Description |
---|---|
merchantId* | Your unique merchant ID. |
currency* | Currency code (3 letters). |
returnUrl* | Base64 encoded URL where users will be redirected at the end or where they will be redirected if they choose to cancel current action. |
customer.email* | Customer email address". |
customer.phoneNumber* | Customer phone number (should start with country phone number prefix). |
customer.deliveryInformation.deliveryType* | Delivery type (e.g.: "Sameday"). |
customer.deliveryInformation.country* | Alpha code of the country set for delivery - 3 letters. |
customer.deliveryInformation.city* | Where you will deliver requested products / services. |
customer.deliveryInformation.address* | Customer physical address set for delivery |
customer.billingInformation.country* | Alpha code of the country set for billing - 3 letters. |
customer.billingInformation.city* | City set for billing |
customer.billingInformation.address* | Customer physical address set for billing |
Delete Card
$cardResponse = $oderopay->cards->delete('cardToken'); //CardSaveResponse
var_dump($cardResponse);
{
"merchantId": "uuid"
}
The above command returns an object like this:
{
"operationId": "uuid",
"message": "string"
}
This endpoint deletes a saved card.
HTTP Request
DELETE /api/cards/{cardToken}
Payments
Create Payment Request
$billingAddress = new \Oderopay\Model\Address\BillingAddress();
$billingAddress
->setAddress('185 Berry St #550, San Francisco, CA 94107, USA')
->setCity('San Francisco')
->setCountry('USA');
$deliveryAddress = new \Oderopay\Model\Address\DeliveryAddress();
$deliveryAddress
->setAddress('185 Berry St #550, San Francisco, CA 94107, USA')
->setCity('San Francisco')
->setCountry('USA')
->setDeliveryType('Courier');
$customer = new \Oderopay\Model\Payment\Customer();
$customer
->setEmail('customer@email.com')
->setPhoneNumber(' +19159969739')
->setDeliveryInformation($deliveryAddress)
->setBillingInformation($billingAddress);
$products = [];
$product1 = new \Oderopay\Model\Payment\BasketItem();
$product1
->setExtId('123')
->setImageUrl('https://site.com/image/product1.jpg')
->setName('Product Name')
->setPrice(99.99)
->setQuantity(1);
$products[] = $product1;
$product2 = new \Oderopay\Model\Payment\BasketItem();
$product2
->setExtId('123')
->setImageUrl('https://site.com/image/product1.jpg')
->setName('Product Name')
->setPrice(99.99)
->setQuantity(1);
$products[] = $product2;
$paymentRequest = new \Oderopay\Model\Payment\Payment();
$paymentRequest
->setAmount(100.00)
->setCurrency('USD')
->setExtOrderId('external-random-id')
->setExtOrderUrl('https://mystore.com/sample-product.html')
->setSuccessUrl('https://mystore.com/order/xxxx/?success=true')
->setFailUrl('https://mystore.com/order/xxxx/payment_failed')
->setMerchantId('{merchant-id}')
->setCustomer($customer)
->setProducts($products)
;
$payment = $oderopay->payments->create($paymentRequest); //PaymentIntentResponse
if($payment->isSuccess()){
return http_redirect($payment->data['url'])
}else{
log($payment->message);
}
{
"merchantId": "uuid",
"amount": "float",
"currency": "string",
"extOrderId": "string",
"extOrderUrl": "string",
"returnUrl": "string",
"successUrl": "string",
"failUrl": "string",
"saveCard": "bool",
"recurring": false,
"submerchants": [
{
"extId": "uuid",
"name": "string",
"amount": "float",
"commission": "float",
"products": [
{
"extId": "string",
"price": "float",
"quantity": "float",
"total": "float",
"name": "string",
"imageUrl": "string"
}
]
}
],
"customer": {
"email": "string",
"phoneNumber": "string",
"deliveryInformation": {
"deliveryType": "string",
"country": "string",
"city": "string",
"address": "string"
},
"billingInformation": {
"country": "string",
"city": "string",
"address": "string"
}
}
}
The above command returns an object like this:
{
"operationId": "uuid",
"message": "string",
"data": {
"paymentId": "uuid",
"url": "string"
}
}
This endpoint creates a payment request and returns the url of hosted payment page if success. You are an ecommerce company and selling your own products.
HTTP Request
POST /api/payments/one-time
Body
Parameter | Description |
---|---|
merchantId* | Your unique merchant ID. |
cardToken | Stored card token. |
amount* | Payment amount. |
currency* | Currency code (3 letters). |
extOrderId* | Your internal order ID. |
extOrderUrl* | Base64 encoded order URL |
successUrl* | Base64 encoded URL to return on success |
failUrl* | Base64 encoded URL to return on fail |
returnUrl* | Base64 encoded URL where users will be redirected at the end or where they will be redirected if they choose to cancel current action. |
saveCard | Would you like to save credit card and receive a specific stored card token? |
recurring* | boolean, default false. |
customer.email* | Customer email address". |
customer.phoneNumber* | Customer phone number (should start with country phone number prefix). |
customer.deliveryInformation.deliveryType* | Delivery type (e.g.: "Sameday"). |
customer.deliveryInformation.country* | Alpha code of the country set for delivery - 3 letters. |
customer.deliveryInformation.city* | Where you will deliver requested products / services. |
customer.deliveryInformation.address* | Customer physical address set for delivery |
customer.billingInformation.country* | Alpha code of the country set for billing - 3 letters. |
customer.billingInformation.city* | City set for billing |
customer.billingInformation.address* | Customer physical address set for billing |
Create Payment Link
$paymentRequest = new \Oderopay\Model\Payment\PaymentLink();
$paymentRequest
->setItemDescription('Sample Product')
->setCurrency('RON')
->setAmount(5.20)
->setExpireAt((new DateTime())->add(new DateInterval("P1Y")))
;
try {
$payment = $oderopay->payments->create($paymentRequest); //PaymentIntentResponse
var_dump($payment);
}catch (\Exception $e){
echo $e->getMessage();
}
{
"merchantId": "uuid",
"amount": "float",
"currency": "string",
"expireAt": "string",
"itemDescription": "string"
}
The above command returns an object like this:
{
"operationId": "uuid",
"message": "string",
"data": {
"paymentId": "uuid",
"url": "string",
"qr" : "string"
}
}
This endpoint creates a payment link request and returns the url of hosted payment page if success. Qr is the url of QrCode that could be used directly as image.
HTTP Request
POST /api/payments/link
Body
Parameter | Description |
---|---|
merchantId* | Your unique merchant ID. |
amount* | Payment amount. |
currency* | Currency code (3 letters). |
itemDescription* | Product or Service name |
expireAt* | Expiration date of the link |
Get Payment
$payment = $oderopay->payments->get('payment-id');
The above command returns object like this:
{
"operationId": "uuid",
"message": "string",
"data": {
"paymentId": "uuid",
"url": "string"
}
}
To get a single payment object, you can call this endpoint.
HTTP Request
GET /api/payments/{id}
Marketplace
$customer = new Customer();
....
$product1 = new \Oderopay\Model\Payment\BasketItem();
$product1
->setExtId('123')
->setImageUrl('https://site.com/image/product1.jpg')
->setName('Product Name')
->setPrice(99.99)
->setQuantity(1);
$merchant1Products[] = $product1;
//initialize first merchant
$merchant1 = new \Oderopay\Model\Payment\Merchant();
$merchant1
->setName('Sub Merchant Name')
->setExtId('uuid')
->setProducts($merchant1Products)
->setAmount(90)
->setCommission(0.2)
$product2 = new \Oderopay\Model\Payment\BasketItem();
$product2
->setExtId('123')
->setImageUrl('https://site.com/image/product2.jpg')
->setName('Product Name')
->setPrice(99.99)
->setQuantity(2);
$merchant2Products[] = $product2;
//initialize second merchant
$merchant2 = new \Oderopay\Model\Payment\Merchant();
$merchant2
->setName('Second Sub Merchant')
->setExtId('uuid')
->setAmount(180)
->setCommission(0.2)
->setProducts($merchant2Products)
$merchants[] = $merchant1;
$merchants[] = $merchant2;
$paymentRequest = new \Oderopay\Model\Payment\Payment();
$paymentRequest
->setAmount(100.00)
->setCurrency('USD')
->setExtOrderId('external-random-id')
->setExtOrderUrl('https://mystore.com/sample-product.html')
->setReturnUrl('https://mystore.com')
->setSuccessUrl('https://mystore.com/order/123213?success')
->setFailUrl('https://mystore.com/order/123213?failed')
->setMerchantId('{merchant-id}')
->setCustomer($customer)
->setMerchants($merchants) //add merchants data to payment
;
$payment = $oderopay->payments->create($paymentRequest);
{
"merchantId": "uuid",
"amount": "float",
"currency": "string",
"extOrderId": "string",
"extOrderUrl": "string",
"returnUrl": "string",
"successUrl": "string",
"failUrl": "string",
"saveCard": "bool",
"recurring": false,
"submerchants": [
{
"extId": "uuid",
"name": "string",
"amount": "float",
"commission": "float",
"products": [
{
"extId": "string",
"price": "float",
"quantity": "float",
"total": "float",
"name": "string",
"imageUrl": "string"
}
]
}
],
"customer": {
"email": "string",
"phoneNumber": "string",
"deliveryInformation": {
"deliveryType": "string",
"country": "string",
"city": "string",
"address": "string"
},
"billingInformation": {
"country": "string",
"city": "string",
"address": "string"
}
}
}
The above command returns object like this:
{
"operationId": "uuid",
"message": "string",
"data": {
"paymentId": "uuid",
"url": "string"
}
}
Lets assume you have multiple sub merchants. And your customer has multiple items from different submerchants in their basket. So that, you need to add each merchant with products to payment object
HTTP Request
POST /api/payments/one-time
URL Parameters
Parameter | Description |
---|---|
merchantId* | Your unique merchant ID. |
cardToken | Stored card token. |
amount* | Payment amount. |
currency* | Currency code (3 letters). |
extOrderId* | Your internal order ID. |
extOrderUrl* | Base64 encoded order URL. |
returnUrl* | Base64 encoded URL where users will be redirected at the end or where they will be redirected if they choose to cancel current action. |
saveCard | Would you like to save credit card and receive a specific stored card token? |
submerchants[n].extId* | Submerchant ID (from Odero PSP). |
submerchants[n].name* | Submerchant Name (from Odero PSP). |
submerchants[n].amount* | Amount to deposit |
submerchants[n].commission* | Submerchant commission. |
submerchants[n].products[n].extId | Product ID from your application. Products collection is not mandatory. |
submerchants[n].products[n].price | Product price from your application. |
submerchants[n].products[n].quantity | Product quantity. |
submerchants[n].products[n].total | Product price * product quantity. |
submerchants[n].products[n].name | Product name. |
submerchants[n].products[n].image | Base64 encoded image URL. |
customer.email* | Customer email address". |
customer.phoneNumber* | Customer phone number (should start with country phone number prefix). |
customer.deliveryInformation.deliveryType* | Delivery type (e.g.: "Sameday"). |
customer.deliveryInformation.country* | Alpha code of the country set for delivery - 3 letters. |
customer.deliveryInformation.city* | Where you will deliver requested products / services. |
customer.deliveryInformation.address* | Customer physical address set for delivery |
customer.billingInformation.country* | Alpha code of the country set for billing - 3 letters. |
customer.billingInformation.city* | City set for billing |
customer.billingInformation.address* | Customer physical address set for billing |
Pay With Saved Card
$customer = new Customer();
....
$merchants[] = $merchants;
$paymentRequest = new \Oderopay\Model\Payment\Payment();
$paymentRequest
->setAmount(100.00)
->setCurrency('USD')
->setExtOrderId('external-random-id')
->setExtOrderUrl('https://mystore.com/sample-product.html')
->setReturnUrl('https://mystore.com')
->setMerchantId('{merchant-id}')
->setCustomer($customer)
->setMerchants($merchants)
->setCardToken('savedCardToken') // 👈 add saved card token to payment
;
$payment = $oderopay->payments->create($paymentRequest);
{
"merchantId": "uuid",
"cardToken": "string",
"amount": "float",
"currency": "string",
"extOrderId": "string",
"extOrderUrl": "string",
"returnUrl": "string",
"saveCard": "bool",
"recurring": false,
"submerchants": [
{
"extId": "uuid",
"name": "string",
"amount": "float",
"commission": "float",
"products": [
{
"extId": "string",
"price": "float",
"quantity": "float",
"total": "float",
"name": "string",
"imageUrl": "string"
}
]
}
],
"customer": {
"email": "string",
"phoneNumber": "string",
"deliveryInformation": {
"deliveryType": "string",
"country": "string",
"city": "string",
"address": "string"
},
"billingInformation": {
"country": "string",
"city": "string",
"address": "string"
}
}
}
The above command returns object like this:
{
"operationId": "uuid",
"message": "string",
"data": {
"paymentId": "uuid",
"url": "string"
}
}
If you want to make the payment with a saved card, you need to add cardToken
parameter to payment object.
HTTP Request
POST /api/payments/one-time
URL Parameters
Parameter | Description |
---|---|
cardToken | Stored card token. |
Subscriptions
Create Subscription
//subscription
$startDate = new DateTime();
$endDate = clone $startDate; $endDate->add(DateInterval::createFromDateString('1 years'));
$subscription = new \Oderopay\Model\Subscription\Subscription();
$subscription->setTimeForBillingUtc('15:00');
$subscription->setStartDate($startDate->format('Y-m-d H:i:s'));
$subscription->setEndDate($endDate->format('Y-m-d H:i:s'));
$subscription->monthly(); //set monthly, weekly or yearly
$paymentRequest = new \Oderopay\Model\Payment\Payment();
$paymentRequest
->setCurrency('USD')
->setExtOrderId('external-random-id')
->setExtOrderUrl('https://mystore.com/orders/3244234')
->setReturnUrl('https://mystore.com/sample-product.html')
->setSuccessUrl('https://mystore.com/order/xxxx/?success=true')
->setFailUrl('https://mystore.com/order/xxxx/payment_failed')
->setCustomer($customer)
->setProducts($products)
->setSubscription($subscription) // 👈 set the subscription
;
$subscriptionRequest = $oderopay->subscriptions->create($paymentRequest); //PaymentIntentResponse
dump($payment);
if($subscriptionRequest->isSuccess()){
//redirect to $payment->data['url'];
}else{
//log the message $subscriptionRequest->message
}
{
"merchantId": "uuid",
"cardToken": "string",
"amount": "float",
"currency": "string",
"extOrderId": "string",
"extOrderUrl": "string",
"returnUrl": "string",
"successUrl": "string",
"failUrl": "string",
"saveCard": "bool",
"recurring": "bool",
"recurringInformation": {
"startDate": "string",
"endDate": "string",
"timeForBillingUtc": "string",
"interval": "string"
},
"submerchants": [
{
"extId": "uuid",
"name": "string",
"amount": "float",
"commission": "float",
"products": [
{
"extId": "string",
"price": "float",
"quantity": "float",
"total": "float",
"name": "string",
"imageUrl": "string"
}
]
}
],
"customer": {
"email": "string",
"phoneNumber": "string",
"deliveryInformation": {
"deliveryType": "string",
"country": "string",
"city": "string",
"address": "string"
},
"billingInformation": {
"country": "string",
"city": "string",
"address": "string"
}
}
}
The above command returns an object like this:
{
"operationId": "uuid",
"message": "string",
"data": {
"paymentId": "uuid",
"url": "string"
}
}
This endpoint creates a payment request and returns the url of hosted payment page if success.
HTTP Request
POST /api/payments/one-time
Body
Parameter | Description |
---|---|
merchantId* | Your unique merchant ID. |
cardToken | Stored card token. |
amount* | Payment amount. |
currency* | Currency code (3 letters). |
extOrderId* | Your internal order ID. |
extOrderUrl* | Base64 encoded order URL. |
returnUrl* | Base64 encoded URL where users will be redirected at the end or where they will be redirected if they choose to cancel current action. |
saveCard | Would you like to save credit card and receive a specific stored card token? |
recurring* | Setting a new recurring payment. |
recurringInformation.startDate | When will start the recurring payment. Datetime ATOM format expected. Required if recurring is true. |
recurringInformation.endDate | When will end the recurring payment. Datetime ATOM format expected. Required if recurring is true. |
recurringInformation.timeForBillingUtc | Hour and minute when we will debit client account. Required if recurring is true. |
recurringInformation.interval | How often you'd like to debit client account. Available options: Weekly, Monthly and Yearly. Required if recurring is true. |
customer.email* | Customer email address". |
customer.phoneNumber* | Customer phone number (should start with country phone number prefix). |
customer.deliveryInformation.deliveryType* | Delivery type (e.g.: "Sameday"). |
customer.deliveryInformation.country* | Alpha code of the country set for delivery - 3 letters. |
customer.deliveryInformation.city* | Where you will deliver requested products / services. |
customer.deliveryInformation.address* | Customer physical address set for delivery |
customer.billingInformation.country* | Alpha code of the country set for billing - 3 letters. |
customer.billingInformation.city* | City set for billing |
customer.billingInformation.address* | Customer physical address set for billing |
Retry
$subscription = $oderopay->subscriptions->retry('payment-id');
{
"merchantId": "uuid"
}
The above command returns object like this:
{
"message": "string"
}
If a recurring payment fails, you might want to retry for transaction manually. To do so, you can call the retry endpoint.
HTTP Request
POST /api/payments/{id}/recurring/retry
Cancel
$payment = $oderopay->subscriptions->cancel('payment-id');
{
"merchantId": "uuid"
}
The above command returns object like this:
{
"operationId": "uuid",
"message": "string",
"data": {
"paymentId": "uuid",
"url": "string"
}
}
YOu might want to cancel the subscription. To do so, you can call cancel endpoint.
HTTP Request
POST /api/payments/{id}/recurring/retry
Webhooks
$payload = @file_get_contents('php://input'); // or $_REQUEST
$message = $oderopay->webhooks->handle(json_decode($payload, true));
switch (true) {
case $message instanceof \Oderopay\Model\Webhook\Payment:
/** @var \Oderopay\Model\Webhook\Payment $message */
$paymentId = $message->getPaymentId();
break;
case $message instanceof \Oderopay\Model\Webhook\Refund:
/** @var Refund $message */
$operationId = $message->getOperationId();
// Then update your data
case $message instanceof \Oderopay\Model\Webhook\StoredCard:
/** @var \Oderopay\Model\Webhook\StoredCard $message */
$cardToken = $message->getCardToken();
// Then update your data
break;
// ... handle other event types
default:
echo 'Received unknown webhook ' . $message->getStatus(); //Should give ERROR
}
Odero uses webhooks (callback) to notify your application when an event happens in your account. Webhooks are particularly useful for asynchronous events like when a customer’s bank confirms a payment, a customer disputes a charge, a recurring payment succeeds, or when collecting subscription payments.
A webhook enables Odero to push real-time notifications to your app. Odero uses HTTPS to send these notifications to your app as a JSON payload. You can then use these notifications to execute actions in your backend systems.
How to create a webhook endpoint
Creating a webhook endpoint is no different from creating any other page on your website. It’s an HTTP or HTTPS endpoint on your server with a URL. If you’re still developing your endpoint on your local machine, it can be HTTP. After it’s publicly accessible, it must be HTTPS. You can use one endpoint to handle several different event types at once, or set up individual endpoints for specific events.
Then update your webhook (callback) url in merchant admin panel. Odero will send notifications to that url.
Webhook types
webhook types could be payment
,deposit
,refund
,reverse
,
stored_card
or remove_stored_card
.
Payment
You will receive a payment message after handshake between customer and bank. It could be successful transaction or not.
$message = $oderopay->webhooks->handle(json_decode($_REQUEST, true));
/** @var \Oderopay\Model\Webhook\Payment $message */
$isDepositMade = $message->isDepositMade();
$operationId = $message->getOperationId();
$cardToken = $message->getCardToken();
$cardExpirationMonth = $message->getExpirationMonth();
$cardExpirationYear = $message->getExpirationYear();
$cardLastFourDigits = $message->getLastFourDigits();
{
"type": "payment",
"operationId": "1ed4a356-55ea-67bc-b39f-83aa9247ea19",
"status": "SUCCESS",
"message": "Payment successful.",
"data": {
"depositMade": false,
"cardToken": null,
"lastFourDigits": null,
"expirationMonth": null,
"expirationYear": null,
"paymentId": "7cbe2ee3-4324-4c0e-b2f6-4fe2920a77de",
"extOrderId": "your order id, given on create payment"
}
}
Parameter | Description |
---|---|
type | payment |
operationId | Each payment operation id is unique. you can use this value on admin panel. |
status | Status of operation |
message | Detailed message of operation |
data.depositMade | (bool) If false, you need to deposit manually. See marketplace documentation. |
data.cardToken | If customer checked the save card option, you will receive the card token to use in future. |
data.lastFourDigits | If customer checked the save card option, card's last for digits |
data.expirationMonth | If customer checked the save card option, card's expire month |
data.expirationYear | If customer checked the save card option, card's expire year |
data.paymentId | Unique payment ID |
data.extOrderId | Order ID at your end that provided on payment create |
Deposit
You will receive deposit message when you manually deposit a payment.
$message = $oderopay->webhooks->handle(json_decode($_REQUEST, true));
/** @var \Oderopay\Model\Webhook\Deposit $message */
$isDepositMade = $message->isDepositMade();
$operationId = $message->getOperationId();
$paymentId = $message->getPaymentId();
{
"type": "deposit",
"operationId": "1ed4a34f-60c8-687a-a14d-d53acf3cde4e",
"status": "SUCCESS",
"message": "Deposit successful.",
"data": {
"paymentId": "9e60d19a-62e0-4d6a-a482-922ff6f01933",
"paymentOperationId": "1ed4a34b-79a1-6fee-ad98-e794f89a217a",
"amount": "50.88"
}
}
Parameter | Description |
---|---|
type | deposit |
operationId | Each payment operation id is unique. you can use this value on admin panel. |
status | Status of operation |
message | Detailed message of operation |
data.paymentId | Unique payment ID |
data.paymentOperationId | Operation ID of payment. |
data.amount | Deposited amount. |
Reverse
If the payment is not deposited, you can reverse the payment.
$message = $oderopay->webhooks->handle(json_decode($_REQUEST, true));
/** @var \Oderopay\Model\Webhook\Reverse $message */
$isDepositMade = $message->isDepositMade();
$operationId = $message->getOperationId();
$paymentId = $message->getPaymentId();
{
"type": "reverse",
"operationId": "1ed4a34f-60c8-687a-a14d-d53acf3cde4e",
"status": "SUCCESS",
"message": "Reverse successful.",
"data": {
"paymentId": "9e60d19a-62e0-4d6a-a482-922ff6f01933",
"paymentOperationId": "1ed4a34b-79a1-6fee-ad98-e794f89a217a",
"amount": "50.88"
}
}
Parameter | Description |
---|---|
type | reverse |
operationId | Each reverse operation id is unique. you can use this value on admin panel. |
status | Status of operation |
message | Detailed message of operation |
data.paymentId | Unique payment ID |
data.paymentOperationId | Operation ID of payment. |
data.amount | Deposited amount. |
Refund
If the payment is deposited, you can refund the payment.
$message = $oderopay->webhooks->handle(json_decode($_REQUEST, true));
/** @var \Oderopay\Model\Webhook\Refund $message */
$isDepositMade = $message->isDepositMade();
$operationId = $message->getOperationId();
$paymentId = $message->getPaymentId();
{
"type": "refund",
"operationId": "1ed4a34f-60c8-687a-a14d-d53acf3cde4e",
"status": "SUCCESS",
"message": "Refund successful.",
"data": {
"paymentId": "9e60d19a-62e0-4d6a-a482-922ff6f01933",
"paymentOperationId": "1ed4a34b-79a1-6fee-ad98-e794f89a217a",
"amount": "50.88"
}
}
Parameter | Description |
---|---|
type | refund |
operationId | Each refund operation id is unique. you can use this value on admin panel. |
status | Status of operation |
message | Detailed message of operation |
data.paymentId | Unique payment ID |
data.paymentOperationId | Operation ID of payment. |
data.amount | Refunded amount. |
Stored Card
If you use stored card feature, you will receive the message as below
$message = $oderopay->webhooks->handle(json_decode($_REQUEST, true));
/** @var \Oderopay\Model\Webhook\StoredCard $message */
$operationId = $message->getOperationId();
$cardToken = $message->getCardToken();
$cardExpirationMonth = $message->getExpirationMonth();
$cardExpirationYear = $message->getExpirationYear();
$cardLastFourDigits = $message->getLastFourDigits();
{
"type": "stored_card",
"operationId": "1ed4ac06-eb95-6a6a-89fb-9b562db4a5db",
"status": "SUCCESS",
"message": "Card saved successful.",
"data": {
"cardToken": "sample token",
"lastFourDigits": "7499",
"expirationMonth": 4,
"expirationYear": 2023
}
}
Parameter | Description |
---|---|
type | stored_card |
operationId | Each store card operation id is unique. you can use this value on admin panel. |
status | Status of operation |
message | Detailed message of operation |
data.cardToken | you will receive the card token to use in payment requests. |
data.lastFourDigits | card's last for digits |
data.expirationMonth | card's expire month |
data.expirationYear | card's expire year |
Remove Card
If you want to remove stored card, you will receive the message below
$message = $oderopay->webhooks->handle(json_decode($_REQUEST, true));
/** @var \Oderopay\Model\Webhook\StoredCard $message */
$cardToken = $message->getCardToken();
{
"type": "remove_stored_card",
"operationId": "1ed4ade7-c4a0-6d00-a09b-ed7e63f1aa16",
"status": "SUCCESS",
"message": "Remove card successful.",
"data": {
"storedCardToken": "7fbe06bc344424724e79703d39382dcfb542bb83217e11c2a1f465ce07268983"
}
}
Parameter | Description |
---|---|
type | remove_stored_card |
operationId | Each store card operation id is unique. you can use this value on admin panel. |
status | Status of operation |
message | Detailed message of operation |
data.storedCardToken | you will receive the card token which has been removed |
Status Codes
Webhook message status codes could be one of the below;
Code |
---|
SUCCESS |
TRANSACTION_DECLINED |
CANCELLED |
REQUEST_IN_PROGRESS |
COMPLETED_PARTIALLY |
EXPIRED |
INVALID_MERCHANT |
INVALID_INPUT |
INVALID_AMOUNT |
INVALID_CARD_NUMBER |
WRONG_CARD_EXPIRATION_DATE |
EXPIRED_CARD |
CVV_MISMATCH |
INCORRECT_PIN |
ALLOWABLE_NUMBER_OF_PIN_TRIES_EXCEEDED |
RESTRICTED_CARD |
INACTIVE_CARD |
INVALID_CARD |
INVALID_TRANSACTION |
TRANSACTION_COULD_NOT_BE_ROUTED |
TRANSACTION_LIMIT_EXCEEDED |
DUPLICATE_TRANSACTION |
REENTER_TRANSACTION |
INSUFFICIENT_FUNDS |
EXCEEDS_WITHDRAWAL_AMOUNT_LIMIT |
NO_ACTION_TAKEN |
ACTION_NOT_ALLOWED_FOR_PAYMENT |
ALREADY_REVERSED |
CARD_LOST_OR_STOLEN |
SUSPECTED_FRAUD |
ISSUER_DECLINED |
SYSTEM_ERROR |
DO_NOT_HONOR |
AUTHENTICATION_FAILED_3DS2 |
UNHANDLED |
Open Source
As Oderopay, we do support open source ecommerce and we created some extensions.
Opencart
After uploading files to your server, run this command
composer require oderopay/odero-php
Installation
- Download the latest version of extension from Github.
- Upload the all files in
upload
directory to your server. - Login to your admin panel and go to Extensions
- List Payment extensions and install Oderopay from the list.
After installation, run composer require oderopay/odero-php
on your server where composer.json file is located.
Your extension is ready for configuration
Configuration
To access configuration list;
- Login to your admin panel and go to Extensions
- List Payment extensions and select Oderopay from the list.
Parameter | Description |
---|---|
Api Type | Live or Testing (sandbox). |
Merchant ID | You Odero MerchantID, you can access this from Odero Merchant Admin |
Token | You Odero Token, you can access this from Odero Merchant Admin |
Payment Value | This value will be replaced on checkout page, you can use translations |
Order Status | The order status will be set after successful transaction |
Order Refund Status | The order status will be set after refund |
Order Reverse Status | The order status will be set after reverse |
Cancel Order Status | The order status will be set after cancel, or going back from payment page. |
Extension Status | Set if the extension is enabled or disabled. |
Webhooks
After a successful installation, we generate url for webhooks. Copy the generated url from Opencart Oderopay extension page and paste to settings under Odero Merchant Admin
Woocommerce
- Download the latest version of extension (zip) from Github.
- Go to Wordpress Admin > Plugins > Add New
- Click Upload Plugin on top
- Select the downloaded zip file and click Install Now button
Configuration
For Woocommerce settings please go to WooCommerce > Settings > Payments
and enable OderoPay
Parameter | Description |
---|---|
Enable/Disable | If yes, customers will see the option for Oderopay on checkout page. |
Title | This is the title for customers to see on checkout page. |
Description | This is the title for customers to see on checkout page. |
Merchant ID | You Odero MerchantID, you can access this from Odero Merchant Admin |
Merchant Token | You Odero Token, you can access this from Odero Merchant Admin |
Sandbox Mode | For development purpose to use Odero staging environment |
Merchant ID | You Odero MerchantID, you can access this from Odero Merchant Admin (STG) |
Merchant Token | You Odero Token, you can access this from Odero Merchant Admin (STG) |
Order Status | You should set order statuses during the payment for your custom checkout flow |
Status On Process | This status is set when customer is redirected to Odero Payment Page (default on-hold ) |
On Payment Failed | This status is set when payment is failed (default failed ) |
On Payment Success | This status is set when payment is success. (default processing ) |
Secret Key | A random pasphrase to secure webhook endpoint for IPN |
Enable Logging | Enable loging for debugging, you can access to logs on WooCommerce > Status > Logs |
Test Cards
Card Number | Date | CVV | Description |
---|---|---|---|
5299121033038343 | 07/24 | 742 | SUCCESS - BT |
5299121032998810 | 07/24 | 081 | SUCCESS - BT |
4140496070360295 | 07/24 | 931 | SUCCESS - BT |
5299121033038343 | 07/24 | 100 | CVV MISMATCH - BT |
4012000300201199 | 12/24 | 111 | SUCCESS - SIBS |
4012000300201074 | 12/24 | 111 | INSUFFICIENT FUNDS - SIBS |
5413330300201293 | 12/24 | 111 | DO NOT HONOUR - SIBS |
- step 1. SMS code: 12345
- step 2. clients password: Parola123$
Errors
The Odero API uses the following error codes:
Error Code | Meaning |
---|---|
400 | Bad Request -- Your request is invalid. |
401 | Unauthorized -- Your API key is wrong. |
403 | Forbidden -- The value requested is hidden for administrators only. |
404 | Not Found -- The specified value could not be found. |
405 | Method Not Allowed -- You tried to access a value with an invalid method. |
406 | Not Acceptable -- You requested a format that isn't json. |
429 | Too Many Requests -- You're requesting too many values! Slow down! |
500 | Internal Server Error -- We had a problem with our server. Try again later. |
503 | Service Unavailable -- We're temporarily offline for maintenance. Please try again later. |