Portal API
The payment portal is the easiest way for you to accept online payments. We provide three ways to integrate:
- Standard URL - good for use on a mailed statement or from a non-authenticated website
- Popup - best option for use from an authenticated website
- Redirect - for use from an authenticated or non-authenticated website
The Popup
and Redirect
options allow you to prepopulate the payment form (
see Prepopulate Feature), which allows for a seamless integration to a PCI-Compliant payment
portal.
For a more advanced integration, any option supports Postback Integration, which will automatically send you the data necessary to retrieve transaction or schedule details via Transaction Service or Schedule Service, respectively.
Configure Portal
Portal Configuration URL:
test url: https://appdemo.pdcflow.com
live url: https://app.pdcflow.com
Since the payment portal is a feature of PDCflow's FlowUI, all configuration of the payment portal needs to be done within our UI. Once you are signed in, go to Configure -> Portal. This will give you the ability to create any number of portals. Within each portal, you have the ability to configure multiple settings such as:
- Set custom portal name. This is used as part of the url you provide to your customers.
- Set the payment accounts for processing. If you have multiple bank accounts, this option would allow each portal to go to a different bank account.
- Enable support for schedule creation. Based on your settings, a user may be given the option to create a payment schedule.
- Default fee amount. All payments will have this fee amount added.
- Ability to hide fields you don't need. For example, if you don't want to collect a physical address for the payer, you can hide all address fields from the form.
- Ability to require fields. You can make any field required. For example, if you need a zip code to get a lower card processing rate, you can require that field.
- Set fields to be readonly. If using the integration below, you can pass values to pre-fill the form, and then use this setting to make sure the value isn't changed by your customer. Warning: If you mark a field as readonly and don't send a value, your customer will not be able to submit the payment.
- Override the company name on file. For example, if your company name is 'The Company A', but the portal you are configuring is to take payments for a company with the name 'Best Company', this setting would allow the listed name on the portal screen and on all receipts to use 'Best Company'.
- Set an url to redirect to after the payment is complete
- Set an url to have transaction details sent to after a payment is complete ( see Postback Integration). Within the portal configuration, you must enable Allow Event Notifications and set a postback url from Configure -> Notifications.
- Change field labels. All fields can be given custom labels. For example, the default 'Account Number' field could be renamed to 'Member ID' if that is what you call your id.
- Apply custom styling to the form. This includes colors, fonts, and spacing.
While this page gives a basic overview of portal setup, additional help can be found next to each setting on the configuration screen. Look for the purple question marks for a description of each setting.
Prepopulate Feature
One of the main features available to integrators is the ability to prepopulate a payment form. This is accomplished by
handling all lookups within your existing system, and then using a POST
to send that information into a PDC
Portal.
The following table describes the individual elements that can receive a prepopulate value. If a portal configuration set a field to hidden, a prepopulate value for that field will be ignored.
Attribute | Description |
---|---|
firstName
Alpha45
|
The first name of your client. |
lastName
Alpha45
|
The last name of your client. |
streetAddressOne
Alphanumeric80
|
The first line of the address. |
streetAddressTwo
Alphanumeric45
|
The second line of the address. |
city
Alphanumeric45
|
The city associated with the transaction. |
state
Alpha2
|
The abbreviation of the state.
Format: two character abbreviation (UT, CA, MI, etc)
|
country
Alpha2
|
The abbreviation of the country. The only reason to set this parameter is if your client is outside of the United States.
Format: two character abbreviation (US, DE, GB, etc)
Default: US
|
zip
Numeric5
|
The zip code associated with the transaction. |
zipPlusFour
Numeric4
|
The four digit extension of the zip code. |
emailAddress
Alphanumeric75
|
The email address of the payer where a receipt will be sent at the completion of the transaction (if enabled in portal configuration). |
phoneNumber
Alphanumeric10
|
Telephone number. All formatting should be removed, as only the first 10 digits will be used in the field.
Format: XXXXXXXXXX
|
accountNumber
Alphanumeric45
|
Account or reference number. This is often the customer account number from your system. |
memo
Alphanumeric50
|
Custom memo information for the explanation of the transaction. |
paymentAmount
Numeric11
|
The payment amount of the transaction or the balance of the account to be used for schedule creation.
Format: XXXX.XX
Do not use any formatting symbols such as currency symbols ($), commas etc. |
feeAmountCard
Numeric11
|
Fee to apply to a card payment. This will supersede any stored amount from the portal configuration. This will only apply if the Portal is set to use an amount based fee.
Format: XXXX.XX
Do not use any formatting symbols such as currency symbols ($), commas etc. |
feePercentCard
Numeric6
|
Fee to apply to a card payment. This will supersede any stored amount from the portal configuration. This will only apply if the Portal is set to use a percentage based fee. Send fee as a percentage value (i.e. 4% should be sent as 4.0000).
Format: X.XXXX
Do not use any formatting symbols such as currency symbols ($), commas etc. |
feeAmountCheck
Numeric11
|
Fee to apply to a check payment. This will supersede any stored amount from the portal configuration. This will only apply if the Portal is set to use an amount based fee.
Format: XXXX.XX
Do not use any formatting symbols such as currency symbols ($), commas etc. |
feePercentCheck
Numeric6
|
Fee to apply to a check payment. This will supersede any stored amount from the portal configuration. This will only apply if the Portal is set to use a percentage based fee. Send fee as a percentage value (i.e. 4% should be sent as 4.0000).
Format: X.XXXX
Do not use any formatting symbols such as currency symbols ($), commas etc. |
flowId
Numeric10
|
The related Flow transaction, often a signature. See Flow Service. This will not be visible on the screen to your users. |
roundTrip
Alphanumeric75
|
This can be used to pass custom key/value pairs with each payment. For example, if you need to track the office a payment was processed through, that can be submitted as a roundTrip, and it will be included with the payment information at the end of processing. You may send up to 3. They should be passed as an html array. The key can be up to 75 characters, and the value can be up to 75 characters. In the example below, the keys are level and office , and the values are A and Scranton .
Format:
<input type="hidden" name="roundTrip[level]" value="A" /> <input type="hidden" name="roundTrip[office]" value="Scranton" /> |
<form action="https://appdemo.pdcflow.com/customerID" method="post">
<input type="submit" value="Payment by credit card" /> <input type="hidden" name="firstName" value="Adam" />
<input type="hidden" name="lastName" value="Test" /> <input type="hidden" name="accountNumber" value="AB1234" />
<input type="hidden" name="paymentAmount" value="5.00" />
<input type="hidden" name="roundTrip[office]" value="Scranton" />
</form>
Use standard hidden fields to submit your information to PDC. This should always be sent as a POST
request.
Popup Option
<div id="myForm">
<form id="pdcPopulate" action="https://appdemo.pdcflow.com/customerID/" method="post" target="launchPdc">
<input type="hidden" name="firstName" value="Adam" /> <input type="hidden" name="lastName" value="Test" />
<input type="hidden" name="accountNumber" value="AB1234" />
<input type="hidden" name="paymentAmount" value="5.00" />
<input type="hidden" name="roundTrip[office]" value="Scranton" />
<input type="submit" value="Pay Now" onclick="openWindow(); return false;">
</form>
</div>
<div id="myWaiting" style="display:none;">
Waiting for payment...
</div>
<div id="myResult" style="display:none;"></div>
<script>
let pdcWindow = '';
/**
* @param {object} event
* @param {object} event.data
* @param {string} event.data.transactionStatus
* @param {string} event.data.paymentMethod
* @param {string} event.data.arrivalId
* @param {string} event.data.transactionId
*/
window.addEventListener('message', (event) => {
if(event.origin === 'https://appdemo.pdcflow.com') {
let myMessage;
if(event.data.transactionStatus === 'APPROVED') {
myMessage = 'Thank you for your payment<br />';
myMessage += 'Result: ' + event.data.transactionStatus + '<br />';
myMessage += 'Method: ' + event.data.paymentMethod + '<br />';
myMessage += 'Arrival: ' + event.data.arrivalId + '<br />';
myMessage += 'Transaction: ' + event.data.transactionId + '<br /><br />';
myMessage += 'If you have your receipt, you can <a href="javascript:pdcWindow.close();">close the payment form</a> now';
}
else {
myMessage = 'Uh-oh, something went wrong with your payment. Try again?<br />';
myMessage += 'Result: ' + event.data.transactionStatus;
}
document.getElementById('myResult').innerHTML = myMessage;
document.getElementById('myResult').style.display = 'block';
document.getElementById('myWaiting').style.display = 'none';
}
});
function openWindow() {
document.getElementById('myForm').style.display = 'none';
document.getElementById('myWaiting').style.display = 'block';
document.getElementById('myResult').innerHTML = '';
document.getElementById('myResult').style.display = 'none';
const h = screen.height * .7;
const w = screen.width * .7;
pdcWindow = window.open('', 'launchPdc', 'toolbar=no,left=100,top=100,menubar=no,width=' + w + ',height=' + h);
document.getElementById('pdcPopulate').submit();
if(pdcWindow === null) {
alert('popup blocked');
}
}
const loop = setInterval(function() {
if(pdcWindow.closed) {
clearInterval(loop);
document.getElementById('myWaiting').style.display = 'none';
if(document.getElementById('myResult').innerHTML === '') {
document.getElementById('myForm').style.display = 'block';
document.getElementById('myResult').innerHTML = 'User closed window prior to completing payment';
document.getElementById('myResult').style.display = 'block';
}
}
}, 1000);
</script>
A portal can be launched in a popup for a seamless user experience. Populating the portal is similar to the prior
example, but needs to be handled a bit different. Standard hidden form fields plus a POST
should still be
used, but a target also needs to be included. All options listed in Prepopulate Feature are
supported.
An additional method is available to receive an update on the result of the payment attempt. For each payment attempt, a
message will be posted using
the
Window.postMessage() API
. The attributes listed in Post Message will be sent.
Redirect Option
<div id="myForm">
<form id="pdcPopulate" action="https://appdemo.pdcflow.com/customerID/" method="post">
<input type="hidden" name="firstName" value="Adam" /> <input type="hidden" name="lastName" value="Test" />
<input type="hidden" name="accountNumber" value="AB1234" />
<input type="hidden" name="paymentAmount" value="5.00" />
<input type="hidden" name="roundTrip[office]" value="Scranton" /> <input type="submit" value="Pay Now">
</form>
</div>
<?php
if(!empty($_GET)) {
if($_GET['transactionStatus'] == 'APPROVED') {
echo 'Thank you for your payment<br />';
echo 'Result: ' . $_GET['transactionStatus'] . '<br />';
echo 'Method: ' . $_GET['paymentMethod'] . '<br />';
echo 'Arrival: ' . $_GET['arrivalId'] . '<br />';
echo 'Transaction: ' . $_GET['transactionId'];
}
else {
echo 'Uh-oh, something went wrong with your payment. Try again?<br />';
echo 'Result: ' . $_GET['transactionStatus'];
}
}
In this redirect option, your user will leave your site, go to PDC, and then return to your site at the end. The URL to be returned to must be configured on the portal within FlowUI. The same attributes as the Post Message will be appended to your url. All options listed in Prepopulate Feature are supported.
Post Message
Basic information about a transaction will be sent back to your system depending on your integration method. The information returned can be used to securely request further detail from Transaction Service or Schedule Service, respectively. The content will always come as JSON, and as POST. This will occur after any successful or failed payment.
Attribute | Description |
---|---|
arrivalId
Numeric20
|
The PDC transaction arrival id, always present. Use this to pull further details on a payment from Transaction Service. Generally only needed if the payment request failed. |
errorList
List
|
List of all errors from attempt. Only present when submitStatus = 'ERROR'
|
paymentMethod
Alpha5
|
The method of payment, always present.
Valid value(s):
CARD , CHECK |
scheduleId
Numeric10
|
The PDC schedule id. Use this to pull further details on a schedule, check the status, etc. from Schedule Service. This value will only be present on a successfully saved schedule. |
scheduleStatus
Alpha6
|
Initial status of schedule if created. Will always be ACTIVE from a portal; otherwise save would have been unsuccessful.
Valid value(s):
ACTIVE - Schedule activated
|
submitStatus
Alpha8
|
Result of the payment attempt, always present.
Valid value(s):
OK - Transaction was processed successfully.ERROR - Some sort of validation or processing error. If neither scheduleStatus nor transactionStatus is present, it was a validation error that can typically be corrected and resubmitted. Otherwise, it was a processing error. |
transactionId
Numeric20
|
The PDC transaction id. Only populated on a successful APPROVED transaction. Use this to pull further details on a payment, check the status, issue a CREDIT, etc. from Transaction Service.
|
transactionStatus
Alpha8
|
Result of the payment attempt, always present.
Valid value(s):
APPROVED - Transaction was processed successfully.DECLINED - The transaction was sent to the vendor, but the vendor declined the transaction. These transactions will typically not be accepted regardless of how many times they are retried.ERROR - An error has occurred and the transaction failed processing. These transactions can typically be resubmitted once the issues have been corrected. |
Post Message sample - successful payment
{
"arrivalId": "1234",
"paymentMethod": "CARD",
"submitStatus": "OK",
"transactionId": "5678",
"transactionStatus": "APPROVED"
}
After a successful payment, 4 attributes will be populated.
Post Message sample - successful schedule + initial payment
{
"arrivalId": "1234",
"paymentMethod": "CARD",
"scheduleId": "02468",
"scheduleStatus": "ACTIVE",
"submitStatus": "OK",
"transactionId": "5678",
"transactionStatus": "APPROVED"
}
After a successful initial payment and schedule, all 6 attributes will be populated.
Post Message sample - successful schedule
{
"paymentMethod": "CARD",
"scheduleId": "02468",
"scheduleStatus": "ACTIVE",
"submitStatus": "OK"
}
After saving a schedule with no payment today, only 3 attributes will be populated.
Post Message sample - failed payment
{
"arrivalId": "1234",
"errorList": {
"generic": "Hard Decline - Insufficient funds (F51)"
},
"paymentMethod": "CARD",
"submitStatus": "ERROR",
"transactionStatus": "DECLINED"
}
On a failed payment attempt, only basic transaction data will be populated.
Post Message sample - failed validation
{
"errorList": {
"firstName": "First name is required",
"lastName": "Last name is required"
},
"paymentMethod": "CARD",
"submitStatus": "ERROR"
}
Form was submitted, but failed some validation. This will be correctable by a user and can be resubmitted.