API Integration Guide
Approach
You can use Zaypay as a webservice. This way your application can talk to Zaypay in the background to provide your application with micropayment-capabilities. This communication will sometimes be initiated by your application (to request a payment to be setup, for instance) or by Zaypay (say, to give your application an update on a payment). All communication is done by sending xml-http-requests back and forth. This document explains all methods the API can perform, and all the details involved.
Tools, Plugins and Examples
Or.. you just might not care about those details! Because using our ready-made PHP-class you never type a single url. Mind you, we will soon be releasing other tools and classes for other languages and frameworks! Upcoming are a rails-plugin and example project and ASP-versions of the PHP-class.
| PHP API class | PHP5 | An OO class that wraps all the API-plumbing. Just call some methods on Zaypay-objects to do the dirty work for you. |
| PHP API example | PHP5 | An example-script that uses (and includes) the API-class, gives a pretty good idea of how this could be used. |
The real details
But then again, that lifting isn't all that heavy. If you use a language or framework we don't have a class for, you can just do the low-level stuff yourself. We'll now discuss details about HTTP-Headers (to set and to expect), how authentication works and what URLS can be used to do what, all with short examples. We use command-line curl in our example requests and display the results for the requests.
Authentication
Anything sent over the wire in plain-text is insecure. We thus recommend you to always use https://secure.zaypay.com in your communication with the API. Authentication is done by means of an "API-key". This randomly generated key is a property of the Price Setting you're using the API on. Should the key get compromised, edit that Price Setting to produce a new random one (and update your scripts accordingly). The Price Setting specific key should be added to the query-sting of any request you send. You can see these query-strings in all upcoming examples.
HTTP-Headers
When you send a request to the API, you want XML back from us. It is important to let Zaypay know this is the requested format. You must do so by sending the appropriate header:
Accept: application/xml
To make that happen with command-line curl you use the -H option like this (the urls are discussed later):
curl -H "Accept: application/xml" \ "https://secure.zaypay.com/82.94.123.123/pay/1/locale_for_ip?key=..."
Not surprisingly, all responses requested that way will be XML, so containing the header:
Content-Type: application/xml
By the way, note that we use an abbreviated API key, not to clutter up the examples too much. A real key is always 32 characters long, and only consists of numbers and letters.
Reference of Methods
Here follows a list of all API-methods, what they were meant to be used for and all their details.
API Method: locale_for_ip
You use this method to let Zaypay find out what country your customer is in, and what default language goes with that. You send Zaypay the ip-address of your customer Zaypay will return an XML-response with the customers 'locale'.
A locale is a combination of a language and a country such as 'en-GB', by the rules of rfc-3066. In this case the language is English and the country is Great Britain.
| Example Request and Response for locale_for_ip | |
|---|---|
| URL | https://secure.zaypay.com/your customers ip-address/pay/price setting id/locale_for_ip |
| mandatory data | key=price setting key |
| example | curl -H "Accept: application/xml" \ "https://secure.zaypay.com/82.94.123.123/pay/1/locale_for_ip?key=..." |
| response | <?xml version="1.0" encoding="UTF-8"?> |
Having determined the locale of your customer will help you present the customer with a language/country-selection form that has the correct country and language pre-selected. For building that form you will need to know what languages and countries your Price Setting supports effectively. That's what the next API method is about. (Please note that at the moment Zaypay only support English. This is very soon to change!)
API Method: list_locales
With this method, you can query your Price Setting to list languages and countries it supports (that is: countries you configured it to support, and languages we have translations for. At the moment this is only English, but it would be wise to support a language-selection-element in your interface for the near future.).
The returned (XML-)list can be used to build a form with two dropdowns for your visitor to alter the selected local with. The Payalogue (example) does the same kind of thing.
Optionally an amount can be specified. This amount will be used to limit the returned Locales to the ones where that amount can be charged. Hold into account that the Price Margin that was set in the used Price Setting will be used to increase the amount if needed, possibly making certain Locales available where there are only payment methods available that can't exactly match the requested amount, but can match the requested amount increased up to the Price Margin percentage. If no amount is specified, the amount from the Price Setting is used. If you don't specify amounts over the API, you can keep it all in the Price Setting which could be convenient.
About amounts
All amounts must be specified in cents. You can optionally add a ISO 4217 currency code directly after the amount. These are valid amounts: 234, 123EUR, 1200ILS. If you specify an amount without currency code it is assumed to be in euros. If you want to charge the equivalent of € 1,23 you use 123 as amount. The API automatically converts to the local currency of the countries that don't have the currency that you used to define the amount.
| Example Request and Response for list_locales | |
|---|---|
| URL | https://secure.zaypay.com/optional_amount/pay/price setting id/list_locales |
| mandatory data | key=price setting key |
| example with amount | curl -X GET -H "Accept: application/xml" \
"https://secure.zaypay.com/123/pay/1/list_locales?key=..." |
| example with amount and currency | curl -X GET -H "Accept: application/xml" \ "https://secure.zaypay.com/123USD/pay/1/list_locales?key=..." |
| example without amount | curl -X GET -H "Accept: application/xml" \ "https://secure.zaypay.com//pay/1/list_locales?key=..." |
| response | <?xml version="1.0" encoding="UTF-8"?> |
API Method: list_payment_methods
This method let's you fetch all payment methods for a certain locale, where obviously the country in the locale makes the difference (not the language). You get a list back of all available payment methods. As with the list_locales-method you can specify an amount, again in euro-cents. In the response, we also send a various types of instructions in the selected language. You will probably find this very useful once we support a lot of languages.
| Example Request and Response for list_payment_methods | ||
|---|---|---|
| URL | https://secure.zaypay.com/optional_amount/locale/pay/price setting id/payments/new | |
| mandatory data | key=price setting key | |
| example with amount | curl -H "Accept: application/xml" \ "https://secure.zaypay.com/123/nl-NL/pay/1/payments/new?key=..." | |
| example without amount | curl -H "Accept: application/xml" \ "https://secure.zaypay.com//nl-NL/pay/1/payments/new?key=..." | |
| response | <?xml version="1.0" encoding="UTF-8"?> | |
API Method: create_payment
Now you know where your customer is from, you've shown what payment methods are available and with some luck your customer has selected a preferred payment method. Now it's time to setup the payment. You use the create_payment method, and send along the API-key and the payment method your customer has selected. We return a full set of information about the prepared payment, with instructions and all kind of other useful data. All you need to do is inform the customer on how to proceed with the actual payment.
Note that the time and time-left variables in the xml are only applicable to payments with the payment method 'phone' and are based on a 'per minute' type. You could test for the existence of these time-variables and only display them when they are found. You might even use them to display a little growing bar as done in the Payalogue. Don't forget to use our various types of unbeatable (and automatically translated) instructions.
Your own variables
One can think of a lot of cases where it would be very convenient to store some extra data of your own (some hash or id known in your application or database) in the payment in our database. This is possible. Just add extra variables to the query-string of the create_payment call, and they will be returned in status-requests to your report_url and be contained by payments in XML-form, such as returned by show_payment. Your extra variables are allowed to use at most 1k bytes, so we suggest you keep well under there.
| Example Request and Response for create_payment | |
|---|---|
| URL | https://secure.zaypay.com/optional_amount/locale/pay/price setting id/payments/create |
| mandatory data | key=price setting key payment_method_id=payment method id |
| example with amount | curl -H "Accept: application/xml" \ "https://secure.zaypay.com/123/nl-NL/pay/1/payments/create?key=...&payment_method_id=1" |
| example without amount | curl -H "Accept: application/xml" \ "https://secure.zaypay.com//nl-NL/pay/1/payments/create?key=...&payment_method_id=1" |
| example without amount, with custom data | curl -H "Accept: application/xml" \ "https://secure.zaypay.com//nl-NL/pay/1/payments/create?key=...&payment_method_id=1&my_id=123" |
| response | <?xml version="1.0" encoding="UTF-8"?> |
That newly created payment (which isn't paid yet) has status "prepared". From now on every time the payment changes state to in_progress, paused, paid or error you will be notified of this fact by a request to your Report URL, that you specified in the used Price Setting. We don't send the actual payment-info to this url, just references to the payment.
Your script should then go and retrieve the payment through the show_payment API method. Fetching the payment-status is done with the show_payment API method. You obviously need to know the API-key of the Price Setting this payment was created through. If you use the integrated Payalogue, we'll send you the same thing, but with the payalogue_id, too. More about this can be found in the Payalogue Usage Guide.
Report URL
Here's an example of such a request to your Report URL as you could find it in your server-log, would your script be called 'report_script.php':
report_script.php?payment_id=1337&message=This%20payment%20changed%20state&price_setting_id=1&status=in_progress
As you can see you get the id of both the Payment involved and the Price Setting it sprang from. Your script should have the API-key for that Price Setting available. The payment status is also sent in this request, however this information should be used with caution. We advise to use the 'show_payment'-method to actively fetch the payment. (If you ensist, you can also use the status-variable directly. You'll have to check the request was coming from Zaypay. Expect requests coming from 82.94.203.60 through 82.94.203.66)
*Please Note!*
It's important we get this message through to your report-script. That's why we require a *specific response* from your script that's living at the report_url. This response must be the 4-character string *ok* (yes, that is including the asterisks). If we don't get that, we'll continue to try to send that request until we do (or give up). You should use this feature to your advantage. If for instance your database is down, you could throw an error message in that response. That way we'll know to retry the request, and you'll still get it when your database comes up again.
API Method: show_payment
The show-payment method will mostly be used from the script that lives on the Report URL, but you could for instance also connect your backend to us this way, so you can fetch the payment-status from our systems whenever you like. To fetch all info about a payment use the following method (note the 3 slashes, they are needed as they delimit the unused spots for amount and locale):
| Example Request and Response for show_payment | |
|---|---|
| URL | https://secure.zaypay.com///pay/price setting id/payments/payment id |
| mandatory data | key=price setting key |
| example | curl -H "Accept: application/xml" \ "https://secure.zaypay.com///pay/1/payments/1234?key=..." |
| response | <?xml version="1.0" encoding="UTF-8"?> |
A payment can be in one of the following statuses: error, expired, gained, in_progress, paid, paid_out, paid_partially, paused, preparation_failed and prepared.
API Method: mark_payload_provided
When a payment is made some goodies must be delivered to the customer. You can use zaypay to register this has happened. This way you can conveniently decide whether a customer is trying to get a free ride without having to keep track of all payments in your own database. You get a 'payload-provided' flag in every xml describing a payment. When you're sure the product is delivered you can call the mark_payload_provided API method to store this fact with the payment in the zaypay database. Would you call the show API method on that payment you would see the product is already provided for the payment.
| Example Request and Response for mark_payload_provided | |
|---|---|
| URL | https://secure.zaypay.com///pay/price setting id/payments/payment id/mark_payload_provided |
| mandatory data | key=price setting key |
| example | curl -H "Accept: application/xml" \ "https://secure.zaypay.com///pay/1/payments/1234/mark_payload_provided?key=..." |
| response | <?xml version="1.0" encoding="UTF-8"?> |