SplitPay

This method is used to create a SplitPay transaction, which combines an initial credit card or eCheck transaction with a trigger to split the proceeds of the first transaction when that transaction ‘settles’ into a ProPay account.  The movement of funds on the split payment does not complete until the underlying credit card charge is completed.

Credit card options
When you perform a SplitPay for a credit card, you can provide card data in several ways:
  • As card-not-present data: ccNum, expDate, CVV2, Address information
  • As track data: track1, track2 (Make sure that you understand the PCI implications of this as they are quite serious.)
  • As encrypted track data: encryptingDeviceType, keySerialNumber, encryptedTrackData, encryptedTrackData2
Using SplitPay with a mobile solution, or with a ProtectPay PMI
If you use one of the mobile solutions, or a PMI that does not support SplitPay directly, but your merchant uses ProPay, you will always get back a ProPay transaction number.  You can create the SplitPay trigger using that transaction number.  Click here to learn more.

More than one trigger
This isn’t possible with this method, but you can create SplitPay triggers directly to split the proceeds of a transaction between multiple parties.  You need to be careful, though, that you aren’t doing something that credit card brands would consider ‘aggregating’ (Using your own merchant account and then paying out multiple parties who actually provides a good or service).  Brands take a pretty dim view of this behavior, and ProPay watches SplitPay closely for signs that unapproved patners are aggregating.
How to call this method?

Example Request

Example Response

Implementation Details
Request Submission

Response Handling

Request Submission

Response Handling

Request Submission

Response Handling

Request Submission

Response Handling

Request Values
Response Values
How to call this method?

You should submit a post of XML data to the following URL
 
HTTP URL(s)
Example Request

Example Response

<?xml version='1.0'?>
<!DOCTYPE Request.dtd>
<XMLRequest>
<certStr>MyCertStr</certStr>
<class>partner</class>
<XMLTrans>
<transType>33</transType>
<accountNum>123456789</accountNum>
<recAccntNum>987654321</recAccntNum>
<amount>500</amount>
<ccNum>4111111111111111</ccNum>
<expDate>0520</expDate>
<secondaryAmount>100</secondaryAmount>
</XMLTrans>
</XMLRequest>
<XMLResponse>
<XMLTrans>
<transType>33</transType>
<status>00</status>
<accountNum>123456</accountNum>
<invNum>cc1</invNum>
<transNum>1</transNum>
<authCode>A11111</authCode>
<AVS>T</AVS>
<recAccntNum>987654321</recAccntNum>
<secondaryTransNum>87</secondaryTransNum>
<responseCode>0</responseCode>
<convertedAmount>100</convertedAmount>
<convertedCurrencyCode>USD</convertedCurrencyCode>
<currencyConversionRate>1</currencyConversionRate>
<NetAmt>0</NetAmt>
<GrossAmt>100</GrossAmt>
<GrossAmtLessNetAmt>100</GrossAmtLessNetAmt>
<PerTransFee>0</PerTransFee>
<Rate>0.00</Rate>
</XMLTrans>
</XMLResponse>
Implementation Details
Request Submission

namespace MSAPI_ProcessTransaction
  {
  using System;
  using System.Collections.Generic;
  using System.IO;
  using System.Linq;
  using System.Net;
  using System.Text;
  using System.Xml;
  using System.Xml.Linq;
  using System.Xml.Serialization;


/*
  ProPay provides the following code “AS IS.”
ProPay makes no warranties and ProPay disclaims all warranties and conditions, express, implied or statutory,
  including without limitation the implied warranties of title, non-infringement, merchantability, and fitness for a particular purpose.
  ProPay does not warrant that the code will be uninterrupted or error free,
  nor does ProPay make any warranty as to the performance or any results that may be obtained by use of the code.
  */
  public class ProcessTransactionTransType33
  {
  public static void ProcessTransaction()
  {
  var processRequest = new XmlTransactionRequest { CertificationString = "YourCertStringGoesHere", TerminalID = "YourTermId", };
  var xmlTransaction = new XmlProcessTransaction
  {
  TransType = "33",
  accountNum = "12345678",
  recAccntNum = "23456789",
  amount = 1000,
  secondaryAmount = 900,
  invNum = "abc123",
  ccNum = "4747474747474747",
  expDate = "0322",
  };
  processRequest.Transactions.Add(xmlTransaction);
  string request = XmlSerializer<XmlTransactionRequest>.WriteToString(processRequest);
  SubmitRequest(request);
  }

private static void SubmitRequest(string request)
  {
  byte[] dataToSend = Encoding.UTF8.GetBytes(request);

// Change the following URL to point to production instead of integration
  WebRequest webRequest = WebRequest.Create("https://xmltest.propay.com/API/PropayAPI.aspx");
  webRequest.Method = "POST";
  webRequest.ContentLength = dataToSend.Length;
  webRequest.ContentType = "text/xml";
  Stream dataStream = webRequest.GetRequestStream();
  dataStream.Write(dataToSend, 0, dataToSend.Length);
  dataStream.Close();

string response = string.Empty;

try
  {
  WebResponse apiResponse = webRequest.GetResponse();


using (StreamReader sr = new StreamReader(apiResponse.GetResponseStream()))
  {
  response += sr.ReadToEnd();
  }
  }
  catch (WebException wex)
  {
  HttpWebResponse httpResponse = wex.Response as HttpWebResponse;
  using (Stream responseStream = httpResponse.GetResponseStream())
  using (StreamReader reader = new StreamReader(responseStream))
  {
  response = reader.ReadToEnd();
  }
  }

 ParseResponse(response);
  }

private static void ParseResponse(string response)
  {
  var load = XDocument.Parse(response);
  var transType = Convert.ToInt32(load.Descendants().First(p => p.Name.LocalName == "transType").Value);
  var status = load.Descendants().First(p => p.Name.LocalName == "status").Value;
  var transNum = load.Descendants().First(p => p.Name.LocalName == "transNum").Value;
  var authCode = load.Descendants().First(p => p.Name.LocalName == "authCode").Value;
  var AVS = load.Descendants().First(p => p.Name.LocalName == "AVS").Value;
  var secondaryTransNum = load.Descendants().First(p => p.Name.LocalName == "secondaryTransNum").Value;
  var responseCode = load.Descendants().First(p => p.Name.LocalName == "responseCode").Value;
  var convertedAmount = load.Descendants().First(p => p.Name.LocalName == "convertedAmount").Value;
  var convertedCurrencyCode = load.Descendants().First(p => p.Name.LocalName == "convertedCurrencyCode").Value;
  var NetAmt = load.Descendants().First(p => p.Name.LocalName == "NetAmt").Value;
  var GrossAmt = load.Descendants().First(p => p.Name.LocalName == "GrossAmt").Value;
  var GrossAmtLessNetAmt = load.Descendants().First(p => p.Name.LocalName == "GrossAmtLessNetAmt").Value;
  var PerTransFee = load.Descendants().First(p => p.Name.LocalName == "PerTransFee").Value;
  var Rate = load.Descendants().First(p => p.Name.LocalName == "Rate").Value;
  }
  }

public class XmlProcessTransaction : XmlTransaction
  {
  [XmlElement("accountNum")]
  public string accountNum = string.Empty;
  [XmlElement("amount")]
  public string amount = string.Empty;
  [XmlElement("recAccntNum")]
  public string recAccntNum = string.Empty;
  [XmlElement("secondaryAmount")]
  public string secondaryAmount = string.Empty;
  [XmlElement("invNum")]
  public string invNum= string.Empty;
  [XmlElement("comment1")]
  public string comment1 = string.Empty;
  [XmlElement("ccNum")]
  public string ccNum = string.Empty;
  [XmlElement("expDate")]
  public string expDate = string.Empty;
  }

public static class XmlSerializer<T>
  {
  public static XmlSerializer Serializer = new XmlSerializer(typeof(T));
  public static string WriteToString(T data)
  {
  return WriteToString(data, Encoding.UTF8);
  }
  public static string WriteToString(T data, Encoding encoding)
  {
  string retVal;
  using (MemoryStream memoryStream = new MemoryStream())
  {
  using (XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, encoding))
  {
  Serializer.Serialize(xmlTextWriter, data);
  }

retVal = encoding.GetString(memoryStream.ToArray());
  }

return retVal;
  }
  }

[XmlInclude(typeof(XmlProcessTransaction))]
  public class XmlTransaction
  {
  [XmlElement("transType")]
  public string TransType = string.Empty;
  }
  [XmlRoot("XMLRequest")]
  public class XmlTransactionRequest
  {
  [XmlElement("certStr")]
  public string CertificationString = string.Empty;
  [XmlElement("termid")]
  public string TerminalID = string.Empty;
  [XmlElement("XMLTrans")]
  public List<XmlTransaction> Transactions = new List<XmlTransaction>();
  }
}

Response Handling

Request Submission

/**
 * ProPay provides the following code “AS IS.” ProPay makes no warranties and
 * ProPay disclaims all warranties and conditions, express, implied or
 * statutory, including without limitation the implied warranties of title,
 * non-infringement, merchantability, and fitness for a particular purpose.
 * ProPay does not warrant that the code will be uninterrupted or error free,
 * nor does ProPay make any warranty as to the performance or any results that
 * may be obtained by use of the code.
 */


<?php
class ProPayApi
{
/* change this to the production url for going live after testing https://api.propay.com */
private $_apiBaseUrl = 'https://xmltestapi.propay.com';

/* for xml */
/** @var \SimpleXMLElement */
private $_xmlRequestObject;
/** @var \SimpleXMLElement */
private $_xmlResponseObject;
/** @var string */
private $_xmlUrl;

/**
* sets the xml request object
* @param string $xmlData - containing XML
* @return $this
*/
public function setXMLRequestData($xmlData) {
$this->_xmlRequestObject = simplexml_load_string($xmlData);
return $this;
}

/**
* @param string $xmlData - containing XML
* @return $this
*/
public function setXMLResponseData($xmlData) {
$this->_xmlResponseObject = simplexml_load_string($xmlData);
return $this;
}

/**
* @return mixed
*/
public function getXMLRequestObject() {
return $this->_xmlRequestObject;
}

/**
* @return mixed
*/
public function getXMLResponseObject() {
return $this->_xmlResponseObject;
}

/**
* @param \SimpleXMLElement $xmlObject
* @return $this
*/
public function setXMLRequestObject(\SimpleXMLElement $xmlObject) {
$this->_xmlRequestObject = $xmlObject;
return $this;
}

/**
* @param \SimpleXMLElement $xmlObject
* @return $this
*/
public function setXMLResponseObject(\SimpleXMLElement $xmlObject) {
$this->_xmlResponseObject = $xmlObject;
return $this;
}

/**
* sets the url for the XML request
* @param string $xmlUrl
* @return $this
*/
public function setXMLUrl($xmlUrl) {
$this->_xmlUrl = $xmlUrl;
return $this;
}

/**
* posts XML to the server
* @return $this
*/
public function postXML() {
$header = [
"Content-type:text/xml; charset=\"utf-8\"",
"Accept: text/xml"
];


$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => $this->_xmlUrl,
CURLOPT_TIMEOUT => 30,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $this->_xmlRequestObject->asXML(),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => $header,
CURLOPT_SSL_VERIFYPEER => 0,
CURLOPT_SSL_VERIFYHOST => 0,
CURLOPT_HTTPAUTH => CURLAUTH_ANY
]);
$result = curl_exec($curl);
$this->_xmlResponseObject = simplexml_load_string($result);
curl_close($curl);
return $this;
}
}

$proPayAPI = new ProPayApi();
$data = "<?xml version='1.0'?>
<!DOCTYPE Request.dtd>
<XMLRequest>
</XMLRequest>";
$simpleXML = new \SimpleXMLElement($data);
$simpleXML->addChild('certStr','cert string here');
$simpleXML->addChild('termid','terminal id here');
$simpleXML->addChild('class','partner');
$simpleXML->addChild('XMLTrans');
$simpleXML->XMLTrans->addChild('transType', 33);
$simpleXML->XMLTrans->addChild('accountNum', 123456789);
$simpleXML->XMLTrans->addChild('recAccntNum', 234567891);
$simpleXML->XMLTrans->addChild('amount', 1000);
$simpleXML->XMLTrans->addChild('secondaryAmount', 900);
$simpleXML->XMLTrans->addChild('invNum', 'abc123');
$simpleXML->XMLTrans->addChild('ccNum', '4747474747474747');
$simpleXML->XMLTrans->addChild('expDate', '1023');

// returns XML
$result =
$proPayAPI->setXMLUrl('https://xmltest.propay.com/API/PropayAPI.aspx')
->setXMLRequestData($simpleXML->asXML())
->postXML()
->getXMLResponseObject()->asXML();

// if you prefer a simpleXML object you just retrieve the object back to work with that
$result = $proPayAPI->getXMLResponseObject();

Response Handling

Request Submission

Response Handling

Request Submission

Response Handling

Request Values

Element

Type

Max

Required

Notes

accountNum

Int(32)

 

Required

Assigned to each account by ProPay

comment1

String

120

Optional

Merchant transaction descriptor.

comment2

String

120

Optional

Merchant transaction descriptor.

currencyCode

String

3

Optional

ISO standard 3 character currency code for a foreign currency transaction. Amex and Discover are not supported on Multi-Currency transactions (Auth in one currency, settle in another)

*Must be an allowed currency code for the merchant account.

invNum

String

50

Best practice

Transactions are rejected as duplicate when the same card is charged for the same amount with the same invoice number, including blank invoices, in a 30 second period.

amount

Integer

 

Required

The value representing the number of pennies in USD, or the number of [currency] without decimals.

recAccntNum

Int(32)

 

Required

ProPay identifier. This is the account to which the split should be pushed off when transaction settles.

secondaryAmount

Int(64)

 

Required

Amount to be split off to the secondary account when transaction settles.

CITMIT Indicator - MasterCard Only - Optional

Element

Type

Max

Required

Notes

CITMITIndicator

String

 

Optional

If the merchant is performing a MasterCard transaciton, then they can send the CITMITIndicator in the XML Request. If providing a CITMITIndicator, you must also provide a valid CITMITSubIndicator. This is for MasterCard only. Valid Values Provided below. Defaults to ‘N’ if not passed. 

CITMITSubIndicator

String

 

Optional

If the merchant is performing a MasterCard transaction, a CITMITSubIndicator may be specified in the XML Request. SubIndicators must have a valid Indicator specified. Valid values are provided below. 

CITMIT Indicator and SubIndicator Values

Element

CITMIT SubIndicator

Transaction type

Example

C1

01
02
03
04

Credential On File 
Standing Order (variable amount, fixed frequency)
Subscription (fixed amount, fixed frequency)
Installment

C101
C102
C103
C104

M1

01
02
03
04

Unscheduled, credential on file
Standing Order (variable amount, fixed frequency)
Subscription (fixed amount, fixed frequency)
Installment

M101
M102
M103
M104

M1

05
06
07
08
Partial Shipment
Related / Delayed charge
No show charge
Resubmission
M205
M206
M207
M208

CITMIT exmaple scenarios: 

  • If a cardholder uses a credential on file to purchase a new item today: Indicator should be C101 (Customer initiated / credential on file) 
  • If a cardholder initiates a purchase and the merchant stored credentials for futre cardholder-initiated purchases: Indicator should be C101
  • If a cardholder purchases and merchant charges a card on file: Indicator should be M101 (merchant initiated / unscheduled card on file)
  • If a cardholder purchases multiple items, shipped at separate times: Indicator should be M205 (merchant initiated / partial shipment)

 

Credit Card Data: Card Not Present - Optional

Element

Type

Max

Required

Notes

ccNum

String

 

Required

Standard cc numbers which must pass Luhn check.

CVV2

String

 

Optional

The Card CVV2 Code. *Accepts both 3 and 4 character types.

expDate

String

 

Required

The expiration date in MMYY format.

addr

String

50

Optional

Cardholder address. AVS does not typically work when cards are issued outside the US. *Max length is 40 for multi-currency transactions.

addr2

String

20

Optional

Cardholder Address second line

addr3

String

100

Optional

Cardholder Address third line

aptNum

String

20

Optional

Cardholder apartment number *Do not use if using addr2 instead

city

String

30

Optional

Cardholder City.

state

String

 

Optional

Cardholder state. *2 character state code submitted in all capital letters

Zip

String

 

Best Practice

Cardholder zip or postal code *Minimum 3 characters maximum 9. ProPay May require this information for merchants to receive best processing rates.

country

String

 

Optional

Cardholder country. Necessary for valid AVS responses on ProPay accounts held in foreign currencies.

cardholderName

String

100

Optional

Not needed if track data used

 

 

Credit Card Data: ProPay Approved Swipe Device - Optional

Element

Type

Max

Required

Notes

encryptedTrack2Data

String

 

Optional*

Some devices encrypt the data on each track separately.

*When track 2 has been encrypted as a separate value this value is required.

encryptedTrackData

String

 

Required

Contents of track 1 or track 1 and 2 submitted as encrypted block.

encryptingDeviceType

String

 

Required

Valid Values:

MagTekM20

MagTekFlash

IdTechUniMag

MagTekADynamo

MagTekDynaMag

RoamData

keySerialNumber

String

 

Required

Value is obtained from the hardware device. This value is required to identify the ProPay hosted decryption key needed to decrypt the Track Data.

 

 

ACH Data - Optional

Element

Type

Max

Required

Notes

AccountNumber

Int(32)

20

Required

Bank account number.

accountType

String

 

Required

Valid values are Checking and Savings

RoutingNumber

Int(32)

9

Required

Valid ABA routing number or CPA EFT code

StandardEntryClassCode

String

3

Required

Valid values are: WEB, TEL, CCD, PPD

PaymentType

String

100

Required

Pass ‘ACH’ If not passed, and ACH data is supplied, an error will be returned. If not passed, Credit Card is assumed

 

 

Fraud Control using Guardian Cyber-Shield - Optional

Element

Type

Max

Required

Notes

SessionId

Guid

36

Required

Required for, and obtained from Threat Metrix fraud prevention solution

InputIpAddress

IP

16

Required

Optional for Threat Metrix. Status 133 is returned when declined by Threat Metrix.

 

 

Specialty Processing - Optional

Element

Type

Max

Required

Notes

billPay

String

 

Optional

Valid values are: Y and N. If a ProPay Merchant Account is set up for Bill Payment, this is always included in the request to the cardholder’s bank no matter what API request specifies.

recurringPayment

String

1

Optional

Valid Values are Y and N. Defaults to N if not passed

DebtRepayment

String

1

Optional

Valid Values are Y and N. Defaults to N if not passed or if an invalid entry is detected

Response Values

Element

Type

Notes

status

String

Result of the transaction request. See ProPay Appendix for result code definitions

AccountNum

Integer

ProPay account number transaction was processed against.

AuthCode

String

The auth code supplied by the issuing bank. *Only returned on a successful transaction.

AVS

String

Issuer returned AVS response. *Most issuers approve even if mismatch, If the business requirements are not met for success on this value the transaction can be voided.

convertedAmount

Integer

Amount expressed in the currency of the merchant account. * Returned on multi-currency transactions.

convertedCurrencyCode

String

ISO standard currency code of the ProPay merchant account. *Returned on multi-currency transactions.

CurrencyConversionRate

Decimal

Exchange rate of the currency conversion. See 3.3 *Returned on multi-currency transactions.

CVV2Resp

String

Issuer returned CVV2 response. *Almost all issuers decline if CVV mismatch.

GrossAmt

Integer

Gross amount of transaction of pennies in USD, or the number of [currency] without decimals.

GrossAmtLessNetAmt

Integer

Total amount of fees charged.

InvNum

String

Echo of the invNum passed in the request

NetAmt

Integer

Net amount of transaction after fees charged.

PerTransFee

Integer

The ProPay set per transaction fee applied to this transaction.

Rate

Decimal

The percentage based fee applied to this transaction.

Resp

String

Textual representation of the issuer returned response code.

Response

String

Returned with the Amex Enhanced Auth Fraud solution

ResponseCode

String

The Issuer returned response code. See ProPay Appendix for response code definitions

TransNum

Integer

The ProPay transaction identifier

RecAccntNum

Integer

The ProPay account identifier of the account to which the split portion of the SplitPay transaction is being sent.

secondaryTransNum

Integer

The transaction identifier of the split portion of the transaction.

CurrencyCode

String

ISO standard 3 character code defines which currency this transaction occurred in

How to call this method?

Example Request

Example Response

Implementation Details
Request Submission

Response Handling

Request Submission

Response Handling

Request Submission

Response Handling

Request Submission

Response Handling

Request Values
Response Values