Implementation, Transaction Processing: Refunding Transactions

The following operations are used to refund previously settled transactions for both SOAP and REST implementations:

Refund Operations
ReturnById (BCP, SVA) ReturnUnlinked (BCP, SVA)

Important! All parameters in each operation are considered "required" unless otherwise noted.


ReturnById

The ReturnById operation is used to perform a linked credit to a cardholder’s account from the merchant’s account based on a previously authorized and settled transaction.

SOAP

Note: In the Return differenceData object, the Amount parameter represents the amount to be credited back to the cardholder. For example:

Captured Amount = 10.00
ReturnById Amount = 4.00
Settled Amount = 6.00 ($4.00 was returned to the customer, $6.00 remains in the merchant account)
Captured Amount = 10.00
ReturnById Amount = 12.00
ERROR: Cannot return for more than the original captured amount.

Operation

Response ReturnById(string sessionToken, Return differenceData, string applicationProfileId, string workflowId);

Parameters

Parameter Data Type Description
sessionToken String The short-lived token used to authenticate to CWS.
differenceData Return Contains the return details based on the original authorized and captured amount.
Note: You must send in BankcardReturn for Bankcard transactions.
applicationProfileId String A token representing the PTLS Socket ID unique to each Service Key and configuration data combination. Returned by the SaveApplicationData operation.
workflowId String Identifies the workflow to use for the transaction. If not supporting custom workflows, pass the servideId returned by GetServiceInformation.

Return Type

Data Type Description
Response Transaction response data.
Note: For Bankcard (BCP) transactions, the response object is BankcardTransactionResponsePro.
For Electronic Checking (ECK) transactions, the response object is ElectronicCheckingTransactionResponse.
For Stored Value Account (SVA) transactions, the response object is StoredValueTransactionResponse.

Exceptions

CWSFault CWSInvalidOperationFault
AuthenticationFault CWSInvalidServiceInformationFault
ExpiredTokenFault CWSOperationNotSupportedFault
InvalidTokenFault CWSTransactionAlreadySettledFault
CWSConnectionFault CWSTransactionFailedFault
CWSExtendedDataNotSupportedFault CWSTransactionServiceUnavailableFault
CWSInvalidMessageFormatFault CWSValidationResultFault

PHP Code Sample


<?php
 
		require_once(dirname(__FILE__) . '/AuthAndCapture.php');
		
		class ReturnById {
			public $Addendum;
			public $TransactionDateTime;
			public $TransactionId;
		}
		
		$returnById = new ReturnById();
		$returnById->TransactionId = $response[2]; //<---Response from AuthAndCapture curl_call
		
		$returnByIdParam = '<ns2:TransactionId xmlns:ns2="http://schemas.ipcommerce.com/CWS/v2.0/Transactions">'.$returnById->TransactionId.'</ns2:TransactionId>
							<ns10:TransactionDateTime xmlns:ns10="http://schemas.ipcommerce.com/CWS/v2.0/Transactions">'.$transactionData->TransactionDateTime.'</ns10:TransactionDateTime>';
		
		$transactionReturnById =  '<?xml version="1.0" encoding="UTF-8"?>
									<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
									  <SOAP-ENV:Body>
										<ReturnById xmlns="http://schemas.ipcommerce.com/CWS/v2.0/TransactionProcessing">
										  <sessionToken>'.$sessionTokenString.'</sessionToken>
										  <differenceData xsi:type="ns1:BankcardReturn" xmlns:ns1="http://schemas.ipcommerce.com/CWS/v2.0/Transactions/Bankcard">'
											.$returnByIdParam.
										 '</differenceData>'
										  .'<applicationProfileId>'.$applicationIdString.'</applicationProfileId>'
										  .'<workflowId>'.$serviceId.'</workflowId>'
										.'</ReturnById>
									   </SOAP-ENV:Body>
									</SOAP-ENV:Envelope>';
									
		
		$xmlRequest = $transactionReturnById;
		$call = 'ReturnById';

		$response = curl_call($xmlRequest, $sessionTokenString, $call);
		
		echo nl2br("<h1>ReturnById Transaction Results</h1> \r\n 
					<h3>StatusMessage: " . $response[0] . "</h3> 
					<h3>StatusCode: "    . $response[1] . "</h3> 
					<h3>TransactionId: " . $response[2] . "</h3> \r\n\r\n
					<h1>We have now returned fundage</h1>");

?>








C# Code Sample


public Response ReturnById(string sessionToken, Return differenceData, string applicationProfileId, string workflowId)
{
	using (var client = new CwsTransactionProcessingClient(ConfigurationManager.AppSettings["Bindings.TxnSoap"]))
	{
		try
		{
			return client.ReturnById(sessionToken, differenceData, applicationProfileId, workflowId);
		}
		catch (FaultException ex)
		{
			SoapFaultHandler.HandleFaultException(ex);
		}
	}
}

REST

Note: The HTTP Authorization Header must contain the required sessionToken value.

Operation

URL https://api.cert.nabcommerce.com/REST/2.0.18/Txn/{workflowId}
UMP URL https://api.cert.nabcommerce.com/REST/2.0.18UMP/Txn/{workflowId}
Action POST

Parameters

Parameter Data Type Description
workflowId String Identifies the workflow to use for the transaction. If not supporting custom workflows, pass the servideId returned by GetServiceInformation.

Message Body Type

Data Type Description
Rest.ReturnById The message body containing transaction data.
Rest.ReturnByIdWithProfile The message body containing transaction data and complete MerchantProfile required by UMP implementations.

Return Type

Data Type Description
Response Transaction response data.
Note: For Bankcard (BCP) transactions, the response object is BankcardTransactionResponsePro.
For Electronic Checking (ECK) transactions, the response object is ElectronicCheckingTransactionResponse.
For Stored Value Account (SVA) transactions, the response object is StoredValueTransactionResponse.

Exceptions

CWSFault CWSInvalidOperationFault
AuthenticationFault CWSInvalidServiceInformationFault
ExpiredTokenFault CWSOperationNotSupportedFault
InvalidTokenFault CWSTransactionAlreadySettledFault
CWSConnectionFault CWSTransactionFailedFault
CWSExtendedDataNotSupportedFault CWSTransactionServiceUnavailableFault
CWSInvalidMessageFormatFault CWSValidationResultFault

For additional details about each fault, refer to Transaction Processing Faults in the CWS Developer API Reference.

PHP Code Sample


/* $transactionID is the known transaction ID of a previous transaction
 * $amount is the amount of money to return, leave it empty to return full amount*/
 
public function returnByID( $transactionID, $creds = null, $amount = null)
{
	if (! $this->signOn ())
		return false;
 
	$TxnType = '"$type":"ReturnById,http://schemas.nabcommerce.com/CWS/v2.0/Transactions/Rest",';
	$DiffDataType = '"$type":"BankcardReturn,http://schemas.nabcommerce.com/CWS/v2.0/Transactions/Bankcard",';
 
	$return_amount = new BankcardReturn ();
	$return_amount->Amount = $amount;
	$return_amount->TransactionId = $transactionID;
	if ($creds != null)
	{
		$return_amount->Addendum = new Addendum ();
		$return_amount->Addendum->Unmanaged = new Unmanaged ();
		$return_amount->Addendum->Unmanaged->Any = new Any ();
		$return_amount->Addendum->Unmanaged->Any->string = $creds;
	}
 
	// Build ReturnById
	$msgBody = new Rest_ReturnById ();
	$msgBody->DifferenceData = $return_amount;
	$msgBody->ApplicationProfileId = $this->appProfileID;
	$action = 'POST';
	$url = $this->txn.'/'.$this->workflowId;
 
	// Format the message
	$txnTypeString = '"ApplicationProfileId"';
	$diffDataTypeString = '"DifferenceData":{';
	$msgBody = (string)json_encode($msgBody);
	$msgBody = str_replace('{'.$txnTypeString, '{'.$TxnType.$txnTypeString, $msgBody);
	$msgBody = str_replace($diffDataTypeString, $diffDataTypeString.$DiffDataType, $msgBody);
	$msgBody = str_replace(' ', '', $msgBody); // Make sure no spaces remain in the body.
	$response = curl_json($msgBody, $url, $action, $this->session_token);
	if(isset($response->body->ErrorId))
	{
		handleRestFault($response);
		return false;
	}
	if(isset($response[2]))
		return $response[2];
}

C# Code Sample


public Response ReturnById(string sessionToken, Return differenceData, string applicationProfileId, string workflowId)
{
	var isJson = string.Equals(_msgFormat, MessageFormat.JSON.ToString());
	var requestString = RestBaseUri + "/" + workflowId;
	var restReturnById = new ReturnById();
	restReturnById.ApplicationProfileId = applicationProfileId;
 
	// Since 'differenceData' references the service reference, this needs to be converted to use the Generated Proxie data contracts 
	// If using REST this step should be avoided by using the generated proxies directly throughout your application. 
	Type type = differenceData.GetType();
	if (type == typeof(BankcardReturn))
		restReturnById.DifferenceData = Utilities.SwapObjectsNamespace(differenceData);
	else if (type == typeof(Return))
		restReturnById.DifferenceData = Utilities.SwapObjectsNamespace(differenceData);
 
	var request = RestHelper.CreateRestRequest(restReturnById, requestString, HttpMethod.POST, sessionToken, isJson);
	try
	{
		if (isJson)
			return RestHelper.GetResponse(request, isJson);
		// For XML the specifc expect response needs to be passed so that it can be deserialized properly. 
		var strResponse = RestHelper.GetResponse(request, isJson, false);
		if (strResponse.Contains("BankcardTransactionResponsePro"))
			return RestHelper.GetCWSObjectFromXml(strResponse);
		if (strResponse.Contains("ElectronicCheckingTransactionResponse"))
			return RestHelper.GetCWSObjectFromXml(strResponse);
		if (strResponse.Contains("StoredValueTransactionResponse"))
			return RestHelper.GetCWSObjectFromXml(strResponse);
	}
	catch (Exception ex)
	{
		RestFaultHandler.HandleFaultException(ex, isJson); 
	}
}

ReturnUnlinked

The ReturnUnlinked operation is used to perform an "unlinked", or standalone, credit to a cardholder’s account from the merchant’s account. This operation is useful when a return transaction is not associated with a previously authorized and settled transaction.

SOAP

Operation

Response ReturnUnlinked(string sessionToken, Transaction transaction, string applicationProfileId, MerchantProfile merchantProfile, string merchantProfileId, string workflowId);

Parameters

Parameter Data Type Description
sessionToken String The short-lived token used to authenticate to CWS.
transaction Transaction Transaction detail data.
Note: You must send in BankcardTransaction for Bankcard transactions.
applicationProfileId String A token representing the PTLS Socket ID unique to each Service Key and configuration data combination. Returned by the SaveApplicationData operation.
merchantProfile MerchantProfile Conditional. The specific Merchant Profile to include in the transaction request. Required only if supporting Unmanaged Merchant Profiles (UMP).
merchantProfileId String The specific Merchant Profile Identifier to use.
workflowId String Identifies the workflow to use for the transaction. If not supporting custom workflows, pass the servideId returned by GetServiceInformation.

Return Type

Data Type Description
Response Transaction response data.
Note: For Bankcard (BCP) transactions, the response object is BankcardTransactionResponsePro.
For Electronic Checking (ECK) transactions, the response object is ElectronicCheckingTransactionResponse.
For Stored Value Account (SVA) transactions, the response object is StoredValueTransactionResponse.

Exceptions

CWSFault CWSInvalidOperationFault
AuthenticationFault CWSInvalidServiceInformationFault
ExpiredTokenFault CWSOperationNotSupportedFault
InvalidTokenFault CWSTransactionAlreadySettledFault
CWSConnectionFault CWSTransactionFailedFault
CWSExtendedDataNotSupportedFault CWSTransactionServiceUnavailableFault
CWSInvalidMessageFormatFault CWSValidationResultFault

For additional details about each fault, refer to Transaction Processing Faults in the CWS Developer API Reference.

PHP Code Sample


<?php
/*
 * SignOnWithToken 
 */
 require_once(dirname(__FILE__) . '/Client.php'); //<---Contains cURL function that sends any transaction related call. 
 require_once(dirname(__FILE__) . '/TransactionClasses.php');
 require_once(dirname(__FILE__) . '/ServiceCalls.php');

 /*
 *Transaction Processing 
 *\See TransactionClasses.php 
 */
 $cardData = new CardData();
 $cardData->PAN = "5100000000000016";
 $cardData->Expire = "1215";
 $cardData->CardType = "MasterCard";
 
 $tenderData = new TenderData();
 $tenderDataParam = '<ns1:TenderData>
 <ns1:CardData>
 <ns1:CardType>'. $cardData->CardType .'</ns1:CardType>
 <ns1:PAN>'.$cardData->PAN . '</ns1:PAN>
 <ns1:Expire>'.$cardData->Expire . '</ns1:Expire>
 </ns1:CardData>
 </ns1:TenderData>';
 
 $dt = date('Y-m-d H:i:s');
 $datetime = str_replace (" ", "T", $dt);
 $transactionData = new TransactionData();
 $transactionData->EntryMode = 'Keyed';
 $transactionData->CustomerPresent = 'Ecommerce';
 $transactionData->TransactionDateTime = $datetime;
 $transactionData->OrderNumber = '123456';
 $transactionData->SignatureCaptured = 'false';
 $transactionData->Amount = '12.00';
 $transactionData->CurrencyCode = 'USD';
 $transactionData->EmployeeId = '11';
 $transactionDataParam = '<ns1:TransactionData>
 <ns8:Amount xmlns:ns8="http://schemas.ipcommerce.com/CWS/v2.0/Transactions">'.$transactionData->Amount.'</ns8:Amount>
 <ns1:CurrencyCode>'.$transactionData->CurrencyCode.'</ns1:CurrencyCode> 
 <ns10:TransactionDateTime xmlns:ns10="http://schemas.ipcommerce.com/CWS/v2.0/Transactions">'.$transactionData->TransactionDateTime.'</ns10:TransactionDateTime>
 <ns1:EntryMode>'. $transactionData->EntryMode . '</ns1:EntryMode>
 <ns1:CustomerPresent>'.$transactionData->CustomerPresent.'</ns1:CustomerPresent>
 <ns1:OrderNumber>' . $transactionData->OrderNumber . '</ns1:OrderNumber>
 <ns1:EmployeeId>' . $transactionData->EmployeeId . '</ns1:EmployeeId>
 <ns1:SignatureCaptured>'.$transactionData->SignatureCaptured.'</ns1:SignatureCaptured>
 </ns1:TransactionData>';
 
 $transaction = new Transaction();
 $transaction->TransactionData = $transactionDataParam;
 $transaction->TenderData = $tenderDataParam;
 $transactionParam = $tenderDataParam . $transactionDataParam;
 
 $transactionReturnUnlinked = '<?xml version="1.0" encoding="UTF-8"?>
 <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
 . '<SOAP-ENV:Body>
 <ReturnUnlinked xmlns="http://schemas.ipcommerce.com/CWS/v2.0/TransactionProcessing">
 <sessionToken>'.$sessionTokenString.'</sessionToken>
 <transaction xmlns:ns1="http://schemas.ipcommerce.com/CWS/v2.0/Transactions/Bankcard" xsi:type="ns1:BankcardTransaction">'
 .$tenderDataParam.
 $transactionDataParam.
 '</transaction>'
 .'<applicationProfileId>'.$applicationIdString.'</applicationProfileId>'
 .'<merchantProfileId>'.$merchantProfileId.'</merchantProfileId>'
 .'<workflowId>'.$serviceId.'</workflowId>'
 .'</ReturnUnlinked>
 </SOAP-ENV:Body>
 </SOAP-ENV:Envelope>';
 
 $call = 'ReturnUnlinked';
 $xmlRequest = $transactionReturnUnlinked;
 
 $response = curl_call($xmlRequest, $sessionTokenString, $call);
 
 echo nl2br("<h1>ReturnUnlinked Transaction Results</h1>
 <h3>StatusMessage: " . $response[0] . "</h3> 
 <h3>StatusCode: " . $response[1] . "</h3> 
 <h3>TransactionId: " . $response[2] . "</h3>
 ");
?>

C# Code Sample


public Response ReturnUnlinked(string sessionToken, Transaction transaction, string applicationProfileId, string merchantProfileId, string workflowId)
{
	using (var client = new CwsTransactionProcessingClient(ConfigurationManager.AppSettings["Bindings.TxnSoap"]))
	{
		try
		{
			return client.ReturnUnlinked(sessionToken, transaction, applicationProfileId, merchantProfileId, workflowId);
		}
		catch (FaultException ex)
		{
			SoapFaultHandler.HandleFaultException(ex);

		}
	}
}

REST

Note: The HTTP Authorization Header must contain the required sessionToken value.

Operation

URL https://api.cert.nabcommerce.com/REST/2.0.18/Txn/{workflowId}
UMP URL https://api.cert.nabcommerce.com/REST/2.0.18UMP/Txn/{workflowId}
Action POST

Parameters

Parameter Data Type Description
workflowId String Identifies the workflow to use for the transaction. If not supporting custom workflows, pass the servideId returned by GetServiceInformation.

Message Body Type

Data Type Description
Rest.ReturnTransaction The message body containing transaction data.
Rest.ReturnTransactionWithProfile The message body containing transaction data and complete MerchantProfile required by UMP implementations.

Return Type

Data Type Description
Response Transaction response data.
Note: For Bankcard (BCP) transactions, the response object is BankcardTransactionResponsePro.
For Electronic Checking (ECK) transactions, the response object is ElectronicCheckingTransactionResponse.
For Stored Value Account (SVA) transactions, the response object is StoredValueTransactionResponse.

Exceptions

CWSFault CWSInvalidOperationFault
AuthenticationFault CWSInvalidServiceInformationFault
ExpiredTokenFault CWSOperationNotSupportedFault
InvalidTokenFault CWSTransactionAlreadySettledFault
CWSConnectionFault CWSTransactionFailedFault
CWSExtendedDataNotSupportedFault CWSTransactionServiceUnavailableFault
CWSInvalidMessageFormatFault CWSValidationResultFault

For additional details about each fault, refer to Transaction Processing Faults in the CWS Developer API Reference.

PHP Code Sample


/* NOTE: See Authorize/AuthorizeAndCapture for structure */
 
public function returnUnlinked( $credit_info, $trans_info)
{
	if (! $this->signOn ())
		return false;
 
	$MsgType = '"$type":"ReturnTransaction,http://schemas.nabcommerce.com/CWS/v2.0/Transactions/Rest",';
	$TxnType = '"$type":"BankcardTransaction,http://schemas.nabcommerce.com/CWS/v2.0/Transactions/Bankcard",';
	$TxnDataType = '"$type" : "BankcardTransactionData,http://schemas.nabcommerce.com/CWS/v2.0/Transactions/Bankcard",';
 
	// Bank Transaction
	$bank_trans = buildTransaction ( $credit_info, $trans_info );
 
	// Build ReturnUnlinked
	$msgBody = new Rest_ReturnTransaction ();
	$msgBody->MerchantProfileId = $this->merchantProfileID;
	$msgBody->ApplicationProfileId = $this->appProfileID;
	$msgBody->Transaction = $bank_trans;
	$action = 'POST';
	$url = $this->txn.'/'.$this->workflowId;
 
	// Format the message
	$msgTypeString = '"ApplicationProfileId"';
	$txnTypeString = '"Transaction":{';
	$txnDataTypeString = '"TransactionData":{';
	$msgBody = (string)json_encode($msgBody);
	$msgBody = str_replace('{'.$msgTypeString, '{'.$MsgType.$msgTypeString, $msgBody);
	$msgBody = str_replace($txnTypeString, $txnTypeString.$TxnType, $msgBody);
	$msgBody = str_replace($txnDataTypeString, $txnDataTypeString.$TxnDataType, $msgBody);
	$msgBody = str_replace(' ', '', $msgBody); // Make sure no spaces remain in the body.
	$response = curl_json($msgBody, $url, $action, $this->session_token);
	if(isset($response->body->ErrorId))
	{
		handleRestFault($response);
		return false;
	}
	if(isset($response[2]))
		return $response[2];
}

C# Code Sample


public Response ReturnUnlinked(string sessionToken, Transaction transaction, string applicationProfileId, string merchantProfileId, string workflowId)
{
	var isJson = string.Equals(_msgFormat, MessageFormat.JSON.ToString());
	var requestString = RestBaseUri + "/" + workflowId;
	var restReturnTransaction = new ReturnTransaction();
	restReturnTransaction.ApplicationProfileId = applicationProfileId;
	restReturnTransaction.MerchantProfileId = merchantProfileId;
	
	Type type = transaction.GetType();
	if (type == typeof(BankcardTransaction))
		restReturnTransaction.Transaction = Utilities.SwapObjectsNamespace(transaction);
	else if (type == typeof(BankcardTransactionPro))
		restReturnTransaction.Transaction = Utilities.SwapObjectsNamespace(transaction);
	else if (type == typeof(ElectronicCheckingTransaction))
		restReturnTransaction.Transaction = Utilities.SwapObjectsNamespace(transaction);
	else if (type == typeof(StoredValueTransaction))
		restReturnTransaction.Transaction = Utilities.SwapObjectsNamespace(transaction);
	else if (type == typeof(Transaction))
		restReturnTransaction.Transaction = Utilities.SwapObjectsNamespace(transaction);
 
	var request = RestHelper.CreateRestRequest(restReturnTransaction, requestString, HttpMethod.POST, sessionToken, isJson);
	try
	{
		if (isJson)
			return RestHelper.GetResponse(request, isJson);
		// For XML the specifc expect response needs to be passed so that it can be deserialized properly. 
		var strResponse = RestHelper.GetResponse(request, isJson, false);
		if (strResponse.Contains("BankcardTransactionResponsePro"))
			return RestHelper.GetCWSObjectFromXml(strResponse);
		if (strResponse.Contains("ElectronicCheckingTransactionResponse"))
			return RestHelper.GetCWSObjectFromXml(strResponse);
		if (strResponse.Contains("StoredValueTransactionResponse"))
			return RestHelper.GetCWSObjectFromXml(strResponse);
	}
	catch (Exception ex)
	{
		RestFaultHandler.HandleFaultException(ex, isJson); 
	}
}

Comments