Refund API
Introduction
PagSeguro API offers an option to Merchant request the refund of a transaction.
A transaction needs to be in status Delivered/Complete in PagSeguro in order to be refunded. The payment method/country of the transaction must be one of which PagSeguro accepts refund. Appendix II has a list of payment methods that are eligible for refund.
How it Works
- Merchant requests refund to PagSeguro
- PagSeguro receives the data and returns the refund identifier to the Merchant
- PagSeguro processes the data transferred by the Merchant
- PagSeguro notifies the Merchant with the status of the transaction change
- Merchant receives notification and updates order status as described in the Notify API topic
Header Specification
For a new API request it is mandatory to format the header as described below:
Parameter | Type | Description |
---|---|---|
Accept | String | This parameter informs the API version, data format (JSON) and encoding. The value will depend on which API you are calling. Refund Create: application/vnd.boacompra.com.v2+json; charset=UTF-8 |
Authorization | String | SHA256 generated with a secret key to guarantee request authenticity. Format: {store-id}:{hash} |
Content-Type | String | Only application/json is accepted at the moment |
Store-id and secret-key are provided by your Account Manager.
POST / HTTP 1.1
Host: api.boacompra.com
Accept: application/vnd.boacompra.com.v2+json; charset=UTF-8
Authorization: 10:52e7178dea75ae0e71e0f8c2379e0278beb7e9d091763ee0a64e6719d2df0fc2
Content-Type: application/json
<?php
class header
{
private $secretKey = 'ABCDE0987';
private $storeId = 10;
public function __construct($content, $url)
{
$this->setContentMd5($content);
$this->setHttpVerb($url);
}
private function setContentMd5($content)
{
$this->contentMd5 = md5($content);
}
private function setHttpVerb($url)
{
if (parse_url($url, PHP_URL_QUERY)) {
$this->httpVerb = parse_url($url, PHP_URL_PATH).'?'.parse_url($url, PHP_URL_QUERY);
} else {
$this->httpVerb = parse_url($url, PHP_URL_PATH);
}
}
private function generateAuthorization()
{
return hash_hmac(
'sha256',
$this->httpVerb . $this->contentMd5,
$this->secretKey
);
}
public function generateHeader()
{
$headers = array(
'Accept' => 'application/vnd.boacompra.com.v2+json; charset=UTF-8',
'Content-Type' => 'application/json',
'Authorization' => $this->storeId . ':' . $this->generateAuthorization()
);
return $headers;
}
}
echo 'POST EXAMPLE <br />';
$content = '{"transaction-id":123456789,"amount":10.57,"notify-url":"https://virtualstore.com/notifications","test-mode":0}';
$headerPost = new header($content, 'https://api.boacompra.com/refunds');
print_r($headerPost->generateHeader());
public class Header {
private String secretKey = "ABCDE0987";
private String storeId = "10";
private String contentMD5;
private String httpVerb;
public Header(String content, String url) 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 {
MessageDigest md = MessageDigest.getInstance("MD5");
byte messageDigest[] = md.digest(content.getBytes("UTF-8"));
this.contentMD5 = new BigInteger(1,messageDigest).toString(16);
}
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.v2+json; charset=UTF-8");
headers.put("Content-Type", "application/json");
headers.put("Authorization", this.storeId+':'+this.generateAuthorization());
return headers;
}
}
String content = "{\"transaction-id\":123456789,\"amount\":10.57,\"notify-url\":\"https://virtualstore.com/notifications\",\"test-mode\":0}";
Header header = new Header(content, "https://api.boacompra.com/refunds");
HashMap<String, String> headerMap = header.generateHeader();
System.out.println(Arrays.asList(headerMap));
require 'uri'
require 'openssl'
require 'digest/md5'
class Header
SECRET_KEY = 'ABCDE0987'
STORE_ID = 10
attr_reader :contentMD5, :httpVerb
def initialize(content, url)
setContentMD5(content)
setHttpVerb(url)
end
private
def setContentMD5(content)
@contentMD5 = Digest::MD5.hexdigest(content).to_s
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 = getQueryString(url).to_s.empty? ? uri.path : 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.v2+json; charset=UTF-8',
"Content-Type" => 'application/json',
"Authorization" => STORE_ID.to_s + ":" + generateAuthorization()
}
headers
end
end
puts '<pre>POST EXAMPLE <br />'
content = '{"transaction-id":123456789,"amount":10.57,"notify-url":"https://virtualstore.com/notifications","test-mode":0}';
headerGet = Header.new(content, 'https://api.boacompra.com/refunds')
puts headerGet.generateHeader()
"""Python 2.7"""
from urlparse import urlparse
import hashlib
import hmac
import md5
class Header:
__secretKey = '123'
__storeId = 10
def __init__(self, content, url):
self.__setHttpVerb(url)
self.__setContentMd5(content)
def __setHttpVerb(self, url):
urlParsed = urlparse(url)
self.__httpVerb = urlParsed.path + urlParsed.query
def __setContentMd5(self, content):
self.__contentMd5 = md5.new(content).hexdigest()
def __generateAuthorization(self):
return hmac.new(
self.__secretKey,
self.__httpVerb + self.__contentMd5,
hashlib.sha256
).hexdigest()
def generateHeader(self):
return {
'Accept': 'application/vnd.boacompra.com.v2+json; charset=UTF-8',
'Content-Type': 'application/json',
'Authorization': str(self.__storeId) + ':' + self.__generateAuthorization()
}
from Header import Header
content = '{"transaction-id":123456789,"amount":10.57,"notify-url":"https://virtualstore.com/notifications","test-mode":0}'
url = 'https://api.boacompra.com/refunds'
a = Header(content, url)
print a.generateHeader()
"""Python 3.x"""
from urllib.parse import urlparse
import hashlib
import hmac
class Header:
__secretKey = '123'
__storeId = 10
def __init__(self, content, url):
self.__setHttpVerb(url)
self.__setContentMd5(content)
def __setHttpVerb(self, url):
urlParsed = urlparse(url)
self.__httpVerb = urlParsed.path + urlParsed.query
def __setContentMd5(self, content):
self.__contentMd5 = hashlib.md5(content.encode()).hexdigest()
def __generateAuthorization(self):
authContent = self.__httpVerb + self.__contentMd5
return hmac.new(
self.__secretKey.encode(),
authContent.encode(),
hashlib.sha256
).hexdigest()
def generateHeader(self):
return {
'Accept': 'application/vnd.boacompra.com.v2+json; charset=UTF-8',
'Content-Type': 'application/json',
'Authorization': str(self.__storeId) + ':' + self.__generateAuthorization()
}
from Header import Header
content = '{"transaction-id":123456789,"amount":10.57,"notify-url":"https://virtualstore.com/notifications","test-mode":0}'
url = 'https://api.boacompra.com/refunds'
a = Header(content, url)
print(a.generateHeader())
Refund Request API
This request must be made in order to create a refund for a given transaction. This only creates the refund: the processing and finishing of this refund is made by PagSeguro directly through the payment provider.
Refund API URL for Production
https://api.boacompra.com/refunds
Method: POST
Input parameters
Parameter | Type | Mandatory? | Description |
---|---|---|---|
transaction-id | Integer | Mandatory | Transaction identifier in PagSeguro. |
notify-url | String | Mandatory | URL used to notify the Merchant. This URL must bind ports 80 or 443. Format: http or https URL format |
amount | Float | Optional | Amount to be refunded. If not sent, the refund will be processed for the entire value of the transaction. For partial refunds, the amount parameter must be sent. Format: 2000.00 |
test-mode | Integer | Optional | Parameter used to indicate that a transaction will be processed in test mode. Can be used the value 1 for sandbox or 0 for production environment. If not set assumes value 0. Format: possible entries are 0 or 1 |
reference | String | Optional | Merchant refund identifier. Limit of 64 characters. |
{
"transaction-id": 123456789,
"amount": 10.57,
"notify-url": "https://virtualstore.com/notifications",
"test-mode": 0,
"reference": "BC-380465"
}
Success Response
HTTP Status code: 201
In case of success, the refund process will be started and the transaction will be set to processing refund status.
Also, a “Location” parameter will be informed in the header with the transaction URI location.
Parameter | Type | Description |
---|---|---|
refund-id | String | Refund identifier code generated by PagSeguro |
HTTP/1.1 201 Created
Content-type: application/vnd.boacompra.com.v2+json; charset=UTF-8
Location: /transactions/123456
{
"refund-id":12345
}
Bank Deposit refund flow
For some payment methods, the refund flow is not automatic - an e-mail will be sent to the end user with URL so he can fulfill information on how they want to receive the refund. In this case, they can choose refund through bank transfer. This process is transparent to the merchant.
This flow can also happen even for automatic payment methods, such as credit card. This is true if the refund is asked after the normal refund period has passed (usually it is 90 days).
When accessing the URL, a form similar to the following image will be displayed.
- Greeting screen where we share important information, such as the need to have a bank account.
- The actual form where the end user fills their data - personal info and bank account info.
After the refund is complete, a notification will be sent via notify API to inform the conclusion of the refund. Please refer to the notification section for further details.
The payer has 7 days to fulfill the form with their information, otherwise the refund will change its status to REJECTED.
Error response
In case of errors in the request, expect a HTTP Status Code different from 201. The body response also contains an error object with the description and an error code.
{
"errors": [
{
"code": "20614",
"description": "transaction_not_found "
}
]
}
The full list of errors can be found here
It is possible that you encounter one or more errors in an error array, which will have a unique code number. In those cases, there is a problem with the Request Body: the need of a property or a constraint is not met.
{
"errors": [
{
"property": "transaction-id",
"constraint": "required",
"code": 20698,
"description": "The property transaction-id is required"
},
{
"property": "amount",
"constraint": "minimum",
"minimum": 0.01,
"code": 20698,
"description": "Must have a minimum value of 0.01"
}
]
}
Refund in Billing Partner
You can view refund requests in the https://billing-partner.boacompra.com. interface for both live transactions and test transactions. Also, there’s a field for filtering specifically by the unique Refund ID number.
In the transaction page a new section, called Refunds, was added. It contains a summary of refund requests.
Test Mode
To use the Refund in test mode you will need to have transactions delivered with the “test-mode” parameter set to true, after sending the request for Refund is it possible to simulate the notification of success and failure in the billing-partner interface.
In the Transaction Test menu it’s possible to find the transaction for which the refund request was made.
In the refund list you can simulate the notification for Success and Failure by clicking in the respective button and a notification will be sent to URL informed on the notify-url refund parameter.
Notification
When a Refund is finished successfully or is rejected for some reason, the merchant will receive a notification in the notification url first sent when creating the refund.
After receiving the notification, the merchant will have to consult the transaction (see section Transaction Search API) and could take an action accordingly its status.
Base URL: notify-url
parameter sent when creating the refund
Method: POST
Notification Object
Parameter | Description |
---|---|
notification-type | Assumes the value “refund” |
refund-id | ID of the refund in PagSeguro |
transaction-id | ID of the transaction in PagSeguro |
Body Example
{
"notification-type": "refund",
"refund-id": 12345,
"transaction-id": 75040384
}
Refund Status
Refund status returned by PagSeguro:
Name | Description |
---|---|
REQUESTED | Refund requested by Customer. |
PROCESSING | Refund in process. |
PROCESSED | Refund successfully completed. |
REJECTED | Refund was rejected. |
Payment Methods Available for Refund
The list of payments and countries with refund available can be found on Available Payment List
Updated over 1 year ago