Transaction Search and Notification
Introduction
We put together this integration manual to provide you all of the information about the technical aspects of transactions notifications and searches.
Work Flow
Transaction Status Notification Change API
How it Works
-
PagSeguro notifies Merchant that a transaction status has changed
-
Merchant requests the transaction information provided in the notification to PagSeguro
-
PagSeguro responds back with the transaction information
COMPLETE
Merchant needs to deliver the purchase to the End User.
Transaction Search API
-
Merchant requests transaction information
-
PagSeguro responds back with a list or a single transaction
Header Specification
For all API requests it is mandatory to format the header as described below:
Parameter | Description |
---|---|
Accept | This parameter informs the API version, data format (JSON) and encoding. Default value is: application/vnd.boacompra.com.v1+json; charset=UTF-8 |
Accept-Language | Input language. Default value is en-US. |
Authorization | To create a request the following information is required: store-id, secret-key, URL Path (e.g. /transactions ) and URL Query String (e.g. ?initial_date=yyyy-mm-dd ). : The string-authorization is done using hmac-sha256-algorithm. The secret-key is the key parameter. The message parameter is formed by the URL Path and URL Query String concatenated. |
Content-Type | application/json |
Headers Example
Accept: application/vnd.boacompra.com.v1+json; charset=UTF-8
Content-Type: application/json
Accept-Language: en-US
Authorization: 10:05eddbf68e09cb3d339b08a8e478c020d50d7c3604ad3da67def785e9399daaa
Generating the Headers
public class Header {
private String secretKey = "YOURSECRETKEY";
private String storeId = "10";
private String contentMD5;
private String httpVerb;
public Header(String url, String content) throws NoSuchAlgorithmException, MalformedURLException, UnsupportedEncodingException {
this.setContentMd5(content);
this.setHttpVerb(new URL(url));
}
private void setHttpVerb(URL url) {
this.httpVerb = url.getPath() + (url.getQuery() != null ? url.getQuery() : "");
}
private void setContentMd5(String content) throws NoSuchAlgorithmException, UnsupportedEncodingException {
if (content == "") {
this.contentMD5 = "";
}else {
MessageDigest md = MessageDigest.getInstance("MD5");
byte messageDigest[] = md.digest(content.getBytes("UTF-8"));
this.contentMD5 = Base64.encodeBase64String(new BigInteger(1,messageDigest).toString(16).getBytes());
}
}
private String generateAuthorization() throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException {
final String data = this.httpVerb+this.contentMD5;
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(this.secretKey.getBytes("UTF8"), "HmacSHA256"));
return Hex.encodeHexString(mac.doFinal(data.getBytes("UTF-8")));
}
public HashMap<String,String> generateHeader() throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException {
HashMap<String, String> headers = new HashMap<>();
headers.put("Accept", "application/vnd.boacompra.com.v1+json; charset=UTF-8");
headers.put("Content-Type", "application/json");
headers.put("Authorization", this.storeId+':'+this.generateAuthorization());
headers.put("Accept-Language", "en-US");
return headers;
}
}
Header header = new Header("https://api.boacompra.com/transactions/87585840", "");
HashMap<String, String> headerMap = header.generateHeader();
System.out.println(Arrays.asList(headerMap));
<?php
class header {
private $_secretKey = 'YOURSECRETKEY';
private $_storeId = '10';
function __construct($url, $content = '') {
$this->_setContentMd5($content);
$this->_setHttpVerb($url);
}
private function _setContentMd5($content) {
if ($content == '') $this->_contentMd5 = '';
else $this->_contentMd5 = base64_encode(md5($content));
}
private function _getQueryString($url){
$queryString = parse_url($url, PHP_URL_QUERY);
return empty($queryString) ? '' : '?' . $queryString;
}
private function _setHttpVerb($url) {
$this->_httpVerb = parse_url($url, PHP_URL_PATH) . $this->_getQueryString($url);
}
private function _generateAuthorization() {
return hash_hmac('sha256', $this->_httpVerb . $this->_contentMd5, $this->_secretKey);
}
public function generateHeader() {
$headers = array(
'Accept' => 'application/vnd.boacompra.com.v1+json; charset=UTF-8',
'Content-Type' => 'application/json',
'Authorization' => $this->_storeId.':'.$this->_generateAuthorization(),
'Accept-Language' => 'en-US'
);
return $headers;
}
}
echo '<pre>'. 'GET EXAMPLE <br />';
$headerGet = new header('https://api.boacompra.com/transactions/87585840', '');
print_r($headerGet->generateHeader());
require 'uri'
require 'base64'
require 'openssl'
require 'digest/md5'
class Header
SECRET_KEY = 'YOURSECRETKEY'
STORE_ID = 10
attr_reader :contentMD5, :httpVerb
def initialize(url, content = '')
setContentMD(content)
setHttpVerb(url)
end
private
def setContentMD(content)
if content.to_s.empty?
@contentMD5 = ''
else
@contentMD5 = Base64.encode64(Digest::MD5.hexdigest(content)).delete!("\n")
end
end
private
def getQueryString(url)
uri = URI(url)
url.to_s.empty? || uri.query.nil? ? '' : '?' + uri.query
end
private
def setHttpVerb(url)
uri = URI::parse(url)
@httpVerb = uri.path + getQueryString(url)
end
private
def generateAuthorization()
OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), SECRET_KEY, @httpVerb + @contentMD5)
end
public
def generateHeader()
headers = {
"Accept" => 'application/vnd.boacompra.com.v1+json; charset=UTF-8',
"Content-Type" => 'application/json',
"Authorization" => STORE_ID.to_s + ":" + generateAuthorization(),
"Accept-Language" => 'en-US'
}
headers
end
end
puts '<pre>GET EXAMPLE <br />'
headerGet = Header.new('https://api.boacompra.com/transactions/87585840', '')
puts headerGet.generateHeader()
"""Boacompra python 2.7"""
import base64
import hashlib
import hmac
from urlparse import urlparse
class Header:
secretKey = "YOURSECRETKEY"
storeId = "10"
def __init__(self, url, content):
self.setContentMd5(content)
self.setHttpVerb(url)
def setContentMd5(self, content):
self.contentMd5 = '' if content == '' else base64.b64encode(hashlib.md5(content).hexdigest())
def setHttpVerb(self, url):
self.httpVerb = '{}''{}'.format(urlparse(url).path, self.getQueryStrint(url))
def getQueryStrint(self, url):
return '' if urlparse(url).query == '' else '?{}'.format(urlparse(url).query)
def generateAuthorization(self):
return hmac.new(self.secretKey, self.httpVerb + self.contentMd5, hashlib.sha256).hexdigest()
def generateHeader(self):
return dict({'Accept':'application/vnd.boacompra.com.v1+json; charset=UTF-8', 'Content-Type':'application/json', 'Authorization': '{}'':{}'.format(self.storeId, self.generateAuthorization()), 'Accept-Language':'en-US'})
"""Boacompra python 3.x"""
import base64
import hashlib
import hmac
from urllib.parse import urlparse
class Header3(object):
secretKey = "YOURSECRETKEY"
storeId = "10"
def __init__(self, url, content):
self.setContentMd5(content)
self.setHttpVerb(url)
self.generateAuthorization()
def setContentMd5(self, content):
self.contentMd5 = ''
if content == ''
else base64.b64encode(hashlib.md5(content.encode()).hexdigest().encode('ascii')).decode('ascii')
def setHttpVerb(self, url):
self.httpVerb = '{}''{}'.format(urlparse(url).path, self.getQueryStrint(url))
def getQueryStrint(self, url):
return '' if urlparse(url).query == '' else '?{}'.format(urlparse(url).query)
def generateAuthorization(self):
message = bytes('{}''{}'.format(self.httpVerb, self.contentMd5), 'utf-8')
secret = bytes(self.secretKey, 3 'utf-8')
return hmac.new(secret, message, hashlib.sha256).hexdigest()
def generateHeader(self):
return dict({'Accept':'application/vnd.boacompra.com.v1+json; charset=UTF-8', 'Content-Type':'application/json', 'Authorization': '{}'':{}'.format(self.storeId, self.generateAuthorization()), 'Accept-Language':'en-US'})
Transaction Status Change Notification
Whenever a transaction has its status changed, PagSeguro will send a POST
notification to the notify-url informed by the Merchant when a transaction was started.
The notification expects a HTTP Status 200
as response. In case such status is not returned, a new notification will be triggered after 10 minutes. Until a successful response is achieved.
Besides HTTP Status 200
as response, notifications of COMPLETE
status expect that the Transaction Search API is accessed for the notified transaction. If a request is not made for such API, notifications will be triggered every 10 minutes as well.
Parameters are described below.
Parameter | Type | Description | |
---|---|---|---|
transaction-code | Required | String | Transaction code. It is the same as “transaction_id” |
notification-type | Required | String | Sent with the literal value "transaction" for this status change notification flow |
test-mode | Required | Boolean | Indicates whether the transaction was created in sandbox environment |
- 177.71.206.83
- 54.233.76.62
- 34.231.230.192
- 34.232.159.3
Example
POST http://your-virtual-store.com/transaction-notification/ HTTP/1.1
Host: boacompra.com
Content-Length:86
Content-Type: application/x-www-form-urlencoded
transaction-code=1234567890
notification-type=transaction
test-mode=false
Transactions Search API
Retrieve information about transactions.
The API can return information about one specific transaction or a list of transactions, based on the search criteria requested via API.
Host: https://api.boacompra.com/transactions/{transactionCode}
Method: GET
Input Parameters
Parameter | Type | Description | |
---|---|---|---|
initial-order-date | Optional | Timestamp | Initial date, based when the order was created, to be searched. Only transactions created after the date sent in this parameter will be returned. If a transactionCode is not sent, a date range search is mandatory. Format: YYYY-MM-DDThh:mm:ss.sTZD Example: 2015-06-09T14:00:00.000-03:00 |
final-order-date | Optional | Timestamp | Final date, based when the order was created, to be searched. Only transactions created before this date will be returned. If an initial-order-date is sent and the final-order-date is left in blank, the current date will be considered unless it is greater than 30 days. In this case, will be considered a 30-day search. If a final-order-date is sent, the parameter initial-order-date is required. Format: YYYY-MM-DDThh:mm:ss.sTZD Example: 2015-06-10T14:00:00.000-03:00 |
initial-payment-date | Optional | Timestamp | Initial date, based when the order was payed, to be searched. Only transactions payed after the date sent in this parameter will be returned. If a transactionCode is not sent, a date range search is mandatory. Format: YYYY-MM-DDThh:mm:ss.sTZD Example: 2015-06-09T14:00:00.000-03:00 |
final-payment-date | Optional | Timestamp | Final date, based when the order was created, to be searched. Only transactions payed before this dates will be returned. If an initial-payment-date is sent and the final-payment-date is left in blank, the current date will be considered unless it is greater than 30 days. In this case, will be considered a 30-day search. If a final-payment-date is sent, the parameter initial-payment-date becomes required. Format: YYYY-MM-DDThh:mm:ss.sTZD **Example: 2015-06-10T14:00:00.000-03:00 |
initial-last-status-change-date | Optional | Timestamp | Initial date, based on the last status change, to be searched. Only transactions with changes on their status after the date sent in this parameter will be returned. If a transactionCode is not sent, a date range search is mandatory. Format: YYYY-MM-DDThh:mm:ss.sTZD |
final-last-status-change-date | Optional | Timestamp | Final date, based on the last status change, to be searched. Only transactions with changes on their status before this dates will be returned. If the initial-last-status-change-date is sent and the final-last-status-change-date is left in blank, the current date will be considered unless it is greater than 30 days. In this case, will be considered a 30-day search. If final-last-status-change-date is sent, the parameter initial-last-status-change-date becomes required. Format: YYYY-MM-DDThh:mm:ss.sTZD Example: 2015-06-10T14:00:00.000-03:00 |
status | Optional | String | Transactions status to be filtered. Values: CANCELLED , COMPLETE , CHARGEBACK , EXPIRED , NOT-PAID , PENDING , REFUNDED , UNDER-REVIEW |
page | Optional | Int | If the search result is presented in more than one page, it’s possible to use this parameter to navigate among the pages. |
max-page-results | Optional | Int | Number of results per page. Default value and maximum accepted is 10. |
In the sequence, a few examples of requests are available:
-
https://api.boacompra.com/transactions/{transactionCode}
- Returns the information of a specific transaction -
https://api.boacompra.com/transactions?initial-order-date=2015-06-10T14:00:00.000-03:00&final-order-date=2015-06-20T14:00:00.000-03:00
- Returns the first ten transactions created on the informed period
Success Response
The response contains metadata information with the number of transactions returned for the request and an array of transaction’s object with the information of each transaction.
HTTP Status Code: 200
Status Description
Name | Description |
---|---|
CANCELLED | Transaction was cancelled by PagSeguro |
COMPLETE | Transaction was paid and approved. Products should be deliver to the End User |
CHARGEBACK | An approved transaction was cancelled by the End User. Please consult your Account Manager for costs. |
EXPIRED | Payment date of transaction expired |
NOT-PAID | Payment confirmation of transaction was not receive. |
PENDING | Transaction was created |
REFUNDED | A partial or full refund was requested and accepted for the transaction |
UNDER-REVIEW | Transaction is under review by PagSeguro Analysis team. It will be approved or cancelled based on the analysis. |
JSON Response example:
{
"transaction-result": {
"store-id": "10",
"transactions": [
{
"transaction-code": "87990145",
"order-id": " 1500397602",
"order-description": "Purchase Test",
"status": "REFUNDED",
"currency": "BRL",
"amount": "10.00",
"customer-email": "[email protected]",
"customer-country": "BR",
"notify-url": "https://loja_teste.international.pagseguro.com/consume_notifications.php",
"payment-country": "BR",
"payment-id": "3",
"payment-name": "mastercard",
"order-date": "2017-07-18T14:18:44-03:00",
"payment-date": "2017-07-18T14:21:02-03:00",
"last-status-change-date": "2017-07-18T14:30:10-03:00",
"chargeback-date": null,
"refundable": false,
"refunds": [
{
"refund-id": "32926",
"refund-status": "PROCESSED",
"refund-amount": "10.00",
"refund-date": "2017-07-18T14:21:47-03:00",
"refund-processing-date": "2017-07-18T00:00:00-03:00",
"refund-reference": "BC-34134"
}
],
"payment-methods": [
{
"code": "123E4567E89B12D3A456426655440000",
"date-created": "2018-04-11T11:31:11.571488493-03:00",
"credit-card": {
"brand": "visa",
"masked-number": "************0002",
"expiration-date": "2026-12"
}
}
],
"payment-response": {
"code": 20000,
"message": "Success"
}
}
]
},
"metadata": {
"found": "1",
"page-results": 1,
"current-page": 1,
"total-pages": 1
}
}
Parameter | Description |
---|---|
transactions-result Object | |
transaction-code | PagSeguro unique identifier for the transaction |
order-id | Merchant unique identifier for the transaction |
order-description | Description provided by the Merchant when the checkout was created |
status | Transaction status |
currency | Currency related to the amount of the transaction |
amount | Amount of the transaction |
customer-mail | Customer e-mail used in PagSeguro checkout |
customer-country | Country in which the customer IP was tracked |
notify-url | URL that PagSeguro notified the Merchant |
payment-country | Country where the payment was made |
payment-id | PagSeguro payment identifier (for more information, check the Integration Guide) |
order-date | Date that the checkout was created |
payment-date | Date that the customer paid the order |
last-status-change-date | Date that the last status change occurred |
chargeback-date | DEPRECATED - Return is null |
refunds Object | |
refund-id | PagSeguro unique identifier for a refund |
refund-status | Status of the refund |
refund-amount | Amount to be refunded |
refund-date | Date that the refund was requested |
refund-processing-date | Date that the refund was paid |
refund-reference | Merchant refund identifier |
payment-methods Object | |
code | Tokenized card code |
date-created | Tokenized card creation date |
credit-cart Object | |
brand | Brand of the credit cart |
masked-number | The last 4 number of the credit card |
expiration-date | Expiration date of the credit cart |
payment-response Object | Returning only when the transaction is “BR”, with “CREDIT CARD” and status “NOT PAID” |
code | Credit card rejection reason code |
message | Detailed credit card reason code message |
Error response
In case of errors in the request, expect a HTTP Status Code different from 200. The body response also contains an error object with the description and an error code, like the following example.
Error Code list here.
Response Body Example:
{
"errors": [
{
"code": "17078",
"description": "currency_not_accepted"
}
]
}
Test Environment
PagSeguro provides a sandbox(test-mode) environment for testing purposes, to create a testing transaction simply send the request to the following endpoint api.sandbox.boacompra.com
For proper simulation of all status and integration flow, PagSeguro offers a panel.
Please access the following URL with credentials provided by your Account Manager.
Host: https://billing-partner.international.pagseguro.com
Search for your test transaction in the “Transactions test” menu:
Once you find it, please click on the “detail” icon:
You can select the status you want to simulate and send a notification by clicking in “Notify”:
Example
POST http://your-virtual-store.com/transaction-notification/ HTTP/1.1
Host: boacompra.com
Content-Length:86
Content-Type: application/x-www-form-urlencoded
transaction-code=1234567890
notification-type=transaction
test-mode=true
A notification will be sent to the URL defined in the notify_url integration field
along with the test-mode parameter.
Errors
Transaction Search API
Code | Key | Description |
---|---|---|
22100 | initial_order_date_invalid | Initial order date has an invalid format |
22101 | final_order_date_invalid | Final order date has an invalid format |
22102 | initial_payment_date_invalid | Initial payment date has an invalid format |
22103 | final_payment_date_invalid | Final payment date has an invalid format |
22104 | initial_last_status_change_date_invalid | Initial last status change date has an invalid format |
22105 | final_last_status_change_date_invalid | Final last status change date has an invalid format |
22106 | initial_order_date_is_mandatory_to_filter_by_final_order_date | Initial order date is mandatory to filter by final order date |
22107 | final_order_date_must_be_greater_than_initial_order_date | Initial order date must be greater than final order date |
22108 | initial_payment_date_is_mandatory_to_filter_by_final_payment_date | Initial payment date is mandatory to filter by final payment date |
22109 | final_payment_date_must_be_greater_than_initial_payment_date | Initial payment date must be greater than final payment date |
22110 | initial_last_status_change_date_is_mandatory_to_filter_by_final_last_status_change_date | Initial last status change date is mandatory to filter by final last status change date |
22111 | final_last_status_change_date_must_be_greater_than_initial_last_status_change_date | Initial last status change date must be greater than final last status change date |
22112 | final_order_date_range_exceeded | Order date range date exceeded |
22113 | final_payment_date_range_exceeded | Order payment range date exceeded |
22114 | final_last_status_change_date_range_exceeded | Order last status change range date exceeded |
22115 | page_invalid | Page has an invalid format |
22116 | max_page_results_invalid | Max page results has an invalid format |
22117 | any_initial_date_is_mandatory_for_multiple_records | TransactionCode or any initial-date is mandatory |
22118 | status_invalid | Transaction status provided is invalid |
22119 | status_not_exists | Transaction status provided does not exists |
22120 | id_invalid | Transaction ID provided has an invalid format |
Search Transaction and Notification
Code | Key | Description |
---|---|---|
30101 | internal_server_error | Error on Boa Compra servers |
Updated about 2 years ago