MENU
PHP CSharp Perl Ruby

Portal API

The payment portal is the easiest way for you to accept online payments. We provide three ways to integrate:

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:

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.


<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.