Overview

This documentation describes the Hyper API. Please make sure you understand the Service Process first. When you decide to integrate Hyper into your website, make sure to check the Integration Guidelines. If you have any questions, problems, or requests, please contact us.

If you have a merchant account, we recommend you log in first, to get examples and information tailored for you.

All API endpoints are accessible through a RESTful HTTP API. For live API calls, all endpoints are available at https://api.payhyper.com/v1/. For sandbox API calls, all endpoints are available at https://sandbox-api.payhyper.com/v1/. You are currently in the live mode. We recommend you switch to the sandbox mode before continuing. You can read more about the modes in the Service Process Documentation.

Language-specific bindings are provided for the Ruby programming language. The bindings give a simple interface to access the API and provides helper functions for common tasks, such as authentication. If you are using these bindings, you may skim over the sections up to the endpoints section.


Format with a JSON-centric approach

All API calls use the JSON format for both requests and responses. Therefore all requests should have their Content-Type header set to application/json, with an optional character set specified. All responses are encoded with UTF-8, and have a header Content-Type: application/json; charset=utf-8.

When an API call allows for parameters to be specified by the caller, they are passed as a JSON object in the body of the HTTP call. The key names of the JSON object should match the parameter names. Parameters are never passed in a query string. The following is an example of an API call to the ping endpoint, with parameter body specified. In this example, and subsequent examples, some non-consequential headers (such as User-Agent, Server, Date and Content-Length) are ignored.

POST /v1/ping HTTP/1.1
Accept: application/json
Content-Type: application/json; charset=utf-8
Host: api.payhyper.com

{"body":"Hello world!"}
HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8

{"body":"Hello world!"}

All dates are formatted according to ISO-8601. For example, the time when this page was loaded was 2023-09-27T15:23:29+00:00.


Authentication based on an HMAC-SHA1 solution

Some endpoints require authentication. Authentication is performed by including three pieces of information in the Authorization HTTP header: a token to identify the authentication method (Hyper in this case), the Access Key ID that uniquely identifies you, and a signature generated using your Access Key Secret. In particular, the content of the Authorization should be Hyper <access-key-id>:<signature>. For the examples in this document, we will assume your Access Key ID is live-de7d244642af41f5a33f525e47e23527, and your Access Key Secret is live-fd91c7ec688a4f39bcd6f0d60d35d2fa. You can log in to have the examples tailored with your Access Key. You can also find your Access Key in your settings page after you log in. Be aware that your Access Key is different in the sandbox mode.

The signature is the Base 64 encoding of an HMAC-SHA1 hash. HMAC-SHA1 takes two parameters (a message, and a key) and generates a hash code, which would be the desired signature. In our case, the message is is comprised of elements from the request organized into what we call the canonical request representation, and the key is the Access Key Secret.

The canonical request representation is constructed by joining the following elements from the request into a single string using newline characters. These elements are, in order:

  • The HTTP method (e.g., POST).
  • The HTTP Host header (e.g., api.payhyper.com), including the port whenever it is not standard (which could happen in notifications for example).
  • The relative request-URI as it appears in the request line (e.g., /v1/ping).
  • The Content-Type header as it appears in the headers, including any possible character set specification (e.g., application/json; charset=utf-8).
  • The body of the request, including any leading or trailing newline characters.

We will now walk through an example of an API call to the authenticated-ping endpoint. The endpoint takes a body parameter, and returns a JSON object with a body key set to the value of the parameter. This endpoint requires authentication, and exists for the sake of testing. Our request prior to setting the Authorization header looks as follows:

POST /v1/authenticated-ping HTTP/1.1
Accept: application/json
Content-Length: 34
Content-Type: application/json; charset=utf-8
Host: api.payhyper.com

{"body":"Testing Authentication."}

Next, we build up the canonical request representation (here \n represents a newline character):

POST\napi.payhyper.com\n/v1/authenticated-ping\napplication/json; charset=utf-8\n{"body":"Testing Authentication."}

Passing the previous string as the message to HMAC-SHA1, and using live-fd91c7ec688a4f39bcd6f0d60d35d2fa as the key, the hash is calculated to be \xF6;Q\x96.\xC9\xCA\xFB\x83;*+6>\x95\xBDb\xF3x#, which when Base-64-encoded yields 9jtRli7JyvuDOyorNj6VvWLzeCM=. This last value is the signature.

It is now possible to build the Authorization header. Knowing that your Access Key ID is live-de7d244642af41f5a33f525e47e23527, the header becomes Authorization: Hyper live-de7d244642af41f5a33f525e47e23527:9jtRli7JyvuDOyorNj6VvWLzeCM=, and the full API call is as follows:

POST /v1/authenticated-ping HTTP/1.1
Accept: application/json
Authorization: Hyper live-de7d244642af41f5a33f525e47e23527:9jtRli7JyvuDOyorNj6VvWLzeCM=
Content-Length: 34
Content-Type: application/json; charset=utf-8
Host: api.payhyper.com

{"body":"Testing Authentication."}
HTTP/1.1 201 Created
Content-Length: 34
Content-Type: application/json; charset=utf-8

{"body":"Testing Authentication."}

Errors

Successful requests return a status code in the 2xx range, and a JSON body specific the API endpoint called. In the case of an error, a status code in the 4xx or 5xx range is returned, along with a JSON object containing a human-friendly message in the error attribute. In particular, validation error result in a status code of 422 Unprocessable Entity.

Below is a non-exhaustive list of errors that could occur.

Non-Existing Endpoint (+)

Incorrect Content Type (+)

Incorrect JSON (+)

Error in Authentication (+)

Validation Error (+)


Endpoints

Currently, three endpoints exist:

  • The orders endpoint, to query orders status.
  • The at-door endpoint, for placing cash collection orders.
  • The ping endpoint, for basic testing of the API.
  • The authenticated-ping endpoint, for testing authentication.

The at-door Endpoint

This endpoint allows the creation of orders, and is the central (and currently only significant) endpoint of the API. This endpoint should be called each time an end-user finishes checking out and wants to pay with Hyper. It returns a representation of the order, including a unique identifier to later refer to this order.

Accessible At https://api.payhyper.com/v1/at-door
HTTP Method POST
Parameters amount Required. Must be greater than zero.
currency Required. Must be one of JOD, USD, BHD, GBP, EGP, KWD, OMR, QAR, SAR, TRY, AED, PKR, IQD.
phone Required. Must start with country dial code and be 11-12 digits long, or otherwise be 8-10 digits long. All non-numeric characters will be removed prior to applying this criteria.
email Required. Must match the regular expression /\A[^@\s]+@([^@\s]+\.)+[^@\s]+\z/.
country Required. Must be a two-character abbreviation for one of the supported countries.
city Required. Must be one of the supported cities.
address Required. No specific format enforced.
tag Required. A tag used to identify this order (for example, the order ID on the merchant platform). It is displayed in the admin interface, and returned in every representation of the order.
Returns An object representing the order, that contains the following fields:
txid The unique identifier of this order.
tag The optional tag assigned to this order when it was created.
status Any of unscheduled, scheduled, successful or failed. Check the Service Process Documentation for more details.
created_at A timestamp representing when this order was created.
completed_at A timestamp representing when this order was completed (that is, when its status turned to either successful or failed). If the order is not yet completed, this field is null.
amount The amount for this order as it currently stands in the database.
currency The currency for this order as it currently stands in the database.
phone The phone number for this order as it currently stands in the database.
email The email address for this order as it currently stands in the database.
Requires Authentication Yes.
You should note the returned txid, to map it to future notifications about this order. Do not depend on the email or phone for mapping, as these could be changed, and are not guaranteed to be unique.

Below is an example of a call to this endpoint.

POST /v1/orders HTTP/1.1
Accept: application/json
Authorization: Hyper live-de7d244642af41f5a33f525e47e23527:wgiUwP3YTjOTDds2YOeW19FdKvQ=
Content-Length: 68
Content-Type: application/json; charset=utf-8
Host: api.payhyper.com

{"amount":"100.1","currency":"JOD","email":"[email protected]","country":"JO","city":"AMMAN","phone":"+962788001234"}
HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8

{
    "amount": 100.1,
    "currency": "USD",
    "completed_at": null,
    "created_at": "2013-05-12T10:17:58+03:00",
    "email": "[email protected]",
    "phone": "+962788001234",
    "status": "unscheduled",
    "txid": "tx-4CkcCbqys28"
}

The ping Endpoint

This endpoint is undocumented at the moment.

The authenticated-ping Endpoint

This endpoint is undocumented at the moment.


Notifications and the Asynchronous Notification Interface (ANI)

Notifications are objects sent from Hyper to inform of a change that might interest the merchant. For the merchant to accept these notifications, they need to implement the Asynchronous Notification Interface (ANI), in a sense, a reverse-API. The ANI is an HTTP interface that accepts POST requests. The body of these requests contain the notification in JSON. The ANI should:

  1. Check the authenticity of the request. The notification is authenticated in a manner similar to API calls (as explained in the Authentication section), and with the same Access Key ID and Acccess Key Secret.
  2. Perform any actions relevant to the delivered notification. For example, if this notification indicates a successfully completed order, fulfill the purchase.
  3. Return a 200 status code to Hyper. If your ANI does not return a 200 status code, Hyper will assume something went wrong, and will try again in a while.

You can specify the URL at which your ANI exists in your settings page (you must log in first).

The notification object contains the following fields:

code An integer representing the event being reported by this notification, this can be one of:
  • 1001: The status of an order has been changed to scheduled.
  • 1002: The status of an order has been changed to successful.
  • 1003: The status of an order has been changed to failed.
resource A representation of the resource affected by this notification. Currently, the only type of resources for which notifications exist are orders. See the documentation of the orders endpoint for details of how this resource is represented.

Next, an example of a call to an ANI living at http://www.example.com/ani:

POST /ani HTTP/1.1
Content-Type: application/json; charset=utf-8
Authorization: Hyper live-de7d244642af41f5a33f525e47e23527:iThuQaPn4PLcQNkynmlnl1LpTdA=
Host: www.example.com

{
  "code": 1001,
  "resource": {
    "txid": "tx-4CkcCbqys28",
    "amount": 100.1,
    "currency": "USD",
    "email": "[email protected]",
    "phone": "+962788001234",
    "status": "scheduled",
    "created_at": "2013-05-12T10:17:58+03:00",
    "completed_at": null
  }
}
HTTP/1.1 200 OK
Content-Length: 0

Bindings for Ruby

You can install the ruby bindings by running gem install payhyper. If you are running Bundler, include gem 'payhyper' in your Gemfile, then run bundle.

The bindings currently provide three exposed methods:

  • PayHyper.setup: For the initial setup of the bindings.
  • PayHyper.create_order!: To create a new order.
  • PayHyper.parse_notification: To be used in the ANI, first checks the authenticity of an ANI call, then returns the parsed notification if valid.

PayHyper.setup(access_key_id, access_key_secret, mode)

This method should be called before any other method under PayHyper. It takes three arguments:

  • access_key_id: Your Access Key ID.
  • access_key_secret: Your Access Key Secret.
  • mode: One of :live or :sandbox.

If you are using Rails, the best place to call PayHyper.setup is in an initializer.

PayHyper.create_order!(params)

This method creates an API call to the orders endpoint, and creates a new order. Its input, params, is a hash containing five keys: :amount, currency, :email, :phone, and :tag.

If the call succeeds, it returns a hash representing the newly-created order. If the call fails, it raises one of two exceptions:

  • PayHyper::ValidationError: If the validations fail. The message of the exception contains a user-friendly error message.
  • PayHyper::CommunicationError: If an error in communication happens, such as not being able to connect to the API server. The message of the exception contains further details.

PayHyper.parse_notification(request)

This method is used to authenticate ANI calls and parse them. Its input, request, is a Rack-compliant request object. If the ANI call is authentic, the method returns a hash representing the notification. If the notification is not authentic, it returns nil.


Coverage Supported countries & cities

Jordan (JO) Amman, Salt, Ramtha, Mafraq, Madaba, Aqaba, Fuhais, Mahes, Zarqa, Rosaifa, Irbid, Maan, Tafileh, Karak, Shoubak, Ajloon, Jerash.
Saudi Arabia (SA) Abha, Abqaiq, Afif, Aflaj, Hassa, Jesh, Arrass, Alghat, Arar, Anak, Shuqaiq, Artawiah, Ayn Fuhayd, Awamiah, Bahara, Bisha, Buraidah, Bukeiriah, Dammam, Dawadmi, Dhahran, Dhurma, Domat Aljandal, Gizan, Hadeethah, Hafer Albatin, Hail, Hareeq, Hawtat Bani Tamim, Hofuf, Hotat Sudair, Jafar, Jeddah, Jubail, Jouf, Khamis Mushait, Kharj, Khobar, Khodaria, Madinah, Majma, Makkah, Mubaraz, Muzahmiah, Najran, Onaiza, Oyaynah, Qassim, Qarah, Qatif, Qurayat, Qasab, Quweiieh, Rahima, Ras Tanura, Riyadh, Rowdat Sodair, Riyadh Alkhabra, Sakaka, Sajir, Safwa, Seihat, Shaqra, Shefa, Shumeisi, Tabuk, Tabrjal, Tarut, Taif, Turaif, Thadek, Udhaliyah, Uyun, Uqlat Alsuqur, Yanbu, Zulfi, Laith, Mastura, Zahban, Asfan, Farasan, Ahad Rufaidah, Sarat Obeida, Wadeien, Tatleeth, Harjah, Dhahran Aljanoob, Sharourah, Turba, Khurma, Nimra, Rabigh, Khulais.
Iraq (IQ) Abu Ghraib, Al Ubaidi, Bakhtyari, Koya, Ain Kawa, Al Baladiyat, Al Bayyaa, Palastine, New Baghdad, Baghdad, Baghdad Airport, Baghdad University, Al Yarmouk, Al Yousifiya, Alsha'ab, Bab Al Muadham, Al Rusafa, Al Sadr City, Al Sha'ab, Al Rashdiya, Al Latifiya, Al Mada'in, Al Mahmoudiya, Al Mansour, Al Jihad, Al Kadhimiya, Al Karkh, Al Sa'adiya, Al Iskan, Makhmour, Arbil, Al Falojah, Al Asmaee, Al Basra Airport, Al Basra University, Madinat Al Basrah, Hay Alhussain, Al Najaf, Al Deewaniya, Al Sinniya, Sulaymaniah, Al Hay Al Askary, Al Hilla, Al Risala, Duhouk, Karbala, Mousl University, Mousl, Tikreet, Al Nasiriya, Al Kut, Kurkuk, Al Rumadi.