Hosted Payments Page

Secure Payment Processing Integration Guide

Event Callbacks

The HPP provides a comprehensive event system to handle all aspects of the payment lifecycle:

Core Payment Events

Event Parameters Description
OnLoaded event (contains CorrelationId) Fired when the payment form has finished loading
OnSuccess response object Payment processed successfully. Contains transaction details including TransactionId, AuthAmount, etc.
OnDecline response object Payment was declined. Contains ResponseMessage and ResponseReason
OnError error detail An error occurred during payment processing
OnWarn warning detail A warning condition was encountered (e.g., BIN lookup failure)

User Interaction Events

Event Parameters Description
OnSubmit amount User clicked submit button. Call SubmitOk() to allow the iframe to submit; do not call it to block submission. Any return value is ignored.
OnCancel detail User clicked cancel button
OnChangePaymentType payment type ("CC", "ACH", "SWIPE") User changed the payment type
OnValidation {fieldId, validationMessage} Form validation error occurred on a specific field

Data Events

Event Parameters Description
OnBinLookupResponse {lookupResult, surchargeAllowed, amountAdjustedTo} BIN lookup completed. Contains card type, issuer, and surcharge eligibility
OnAmountChanged {originalAmount, newAmount, reason} Transaction amount was adjusted (typically due to surcharge changes)
OnGetFieldValue object with field values Response to GetFieldValues() method call

UI Events

Event Parameters Description
OnScrollTop detail Request to scroll parent page to top (typically after validation error)
OnSize {width, height} Iframe size changed. Override to implement custom resizing behavior
OnResponse event Raw message received from iframe (for debugging or custom handling)

Event Handler Examples

Basic Event Handlers

var paymentWidget = new hpp({
    // ... other configuration ...

    OnLoaded: function(event) {
        console.log("Form loaded with correlation ID:", event.CorrelationId);
        // Pre-fill form fields if needed
        paymentWidget.SetFormValues({
            "Request_Name": "John Doe",
            "Request_Email": "john@example.com"
        });
    },

    OnSuccess: function(response) {
        console.log("Payment successful!");
        console.log("Transaction ID:", response.TransactionId);
        console.log("Amount:", response.AuthAmount);
        // Redirect to success page or update UI
        window.location.href = "/payment-success?id=" + response.TransactionId;
    },

    OnDecline: function(response) {
        console.warn("Payment declined:", response.ResponseMessage);
        alert("Your payment was declined: " + response.ResponseMessage);
    },

    OnError: function(error) {
        console.error("Payment error:", error);
        alert("An error occurred while processing your payment. Please try again.");
    }
});

Submit Validation

OnSubmit: function(amount) {
    // Validate on the parent side before allowing submission
    if (amount < 1.00) {
        alert("Amount must be at least $1.00");
        return; // Don't call SubmitOk() - submission is blocked
    }

    // Check terms acceptance
    if (!document.getElementById('terms-checkbox').checked) {
        alert("You must accept the terms and conditions");
        return;
    }

    // Confirm with user
    if (confirm("Process payment of $" + amount + "?")) {
        paymentWidget.SubmitOk();  // Allow submission
    }
    // If you don't call SubmitOk(), submission is blocked
}

Cancel Handler

OnCancel: function(detail) {
    if (confirm("Are you sure you want to cancel?")) {
        // Handle cancellation
        console.log("Payment cancelled:", detail);
        window.location.href = "/checkout";
    }
}

Payment Type Change Handler

OnChangePaymentType: function(paymentType) {
    console.log("Payment type changed to:", paymentType);

    // Update UI based on payment type
    if (paymentType === "ACH") {
        document.getElementById('processing-note').textContent =
            "ACH payments typically take 3-5 business days to process";
        // Show additional ACH-specific fields
        paymentWidget.ToggleFields({
            "Request_Phone": true,
            "Request_Address": true
        });
    } else if (paymentType === "CC") {
        document.getElementById('processing-note').textContent =
            "Credit card payments are processed immediately";
    }
}

BIN Lookup Response Handler

OnBinLookupResponse: function(detail) {
    console.log("Card BIN lookup result:", detail.lookupResult);

    // Display card brand
    if (detail.lookupResult && detail.lookupResult.cardType) {
        document.getElementById('card-brand').textContent =
            "Card Type: " + detail.lookupResult.cardType;
    }

    // Handle surcharge changes
    if (!detail.surchargeAllowed) {
        console.log("Surcharge not allowed for this card");
        console.log("Amount adjusted to:", detail.amountAdjustedTo);
        showMessage("Surcharge removed - this card type is not eligible for surcharges");
    } else {
        console.log("Surcharge allowed for this card");
    }

    // Update display with issuer information
    if (detail.lookupResult.issuerName) {
        console.log("Issuing bank:", detail.lookupResult.issuerName);
    }
}

Amount Changed Handler

OnAmountChanged: function(detail) {
    console.log("Amount changed from", detail.originalAmount, "to", detail.newAmount);
    console.log("Reason:", detail.reason);

    // Update parent page display
    document.getElementById('display-amount').textContent =
        "$" + detail.newAmount.toFixed(2);

    // Show message to user
    if (detail.originalAmount !== detail.newAmount) {
        var message = "Amount adjusted to $" + detail.newAmount.toFixed(2);
        if (detail.reason) {
            message += " (" + detail.reason + ")";
        }
        showNotification(message);
    }

    // Update order summary
    updateOrderSummary({
        total: detail.newAmount,
        surcharge: detail.newAmount - detail.originalAmount
    });
}

Validation Event Handler

OnValidation: function({fieldId, validationMessage}) {
    console.warn("Validation error on", fieldId, ":", validationMessage);

    // Display custom error message in parent page
    var errorContainer = document.getElementById('validation-errors');
    if (errorContainer) {
        var errorDiv = document.createElement('div');
        errorDiv.className = 'alert alert-danger';
        errorDiv.textContent = fieldId + ": " + validationMessage;
        errorContainer.appendChild(errorDiv);

        // Remove error after 5 seconds
        setTimeout(function() {
            errorDiv.remove();
        }, 5000);
    }

    // Log for analytics
    logValidationError(fieldId, validationMessage);
}

Scroll Top Handler

OnScrollTop: function(detail) {
    // Custom scroll behavior - smooth scroll to top
    window.scrollTo({
        top: 0,
        behavior: 'smooth'
    });

    // Or scroll to a specific element
    document.getElementById('payment-container').scrollIntoView({
        behavior: 'smooth',
        block: 'start'
    });
}

Size Change Handler

OnSize: function({width, height}) {
    console.log("Iframe size changed:", width, "x", height);

    // Custom size handling
    var iframe = document.querySelector('#payment-container iframe');
    if (iframe) {
        // Add padding to container based on content height
        if (height > 800) {
            iframe.parentElement.style.padding = '20px';
        } else {
            iframe.parentElement.style.padding = '10px';
        }

        // Adjust parent container min-height
        iframe.parentElement.style.minHeight = height + 'px';
    }
}

Get Field Values Handler

// Request field values
paymentWidget.GetFieldValues({
    "Request_Name": true,
    "Request_Email": true,
    "Request_Postal": true
});

// Handle response
OnGetFieldValue: function(values) {
    console.log("Field values:", values);

    // Use values for custom validation or processing
    if (values.Request_Email) {
        validateEmail(values.Request_Email);
    }

    if (values.Request_Postal) {
        lookupTaxRate(values.Request_Postal);
    }

    // Store values in parent page
    saveCustomerData({
        name: values.Request_Name,
        email: values.Request_Email,
        postalCode: values.Request_Postal
    });
}

All Events Example

var paymentWidget = new hpp({
    Target: "payment-container",
    HPPUrl: "https://your-payment-domain.com/",
    Token: "your-bearer-token",
    MerchantId: "merchant-123",
    ShowPaymentTypeCc: true,
    ShowPaymentTypeAch: true,
    InitialPaymentType: "CC",
    AllowPaymentTypeToggle: true,

    // Core payment events
    OnLoaded: function(event) {
        console.log("Loaded", event);
        trackEvent("payment_form_loaded");
    },

    OnSuccess: function(response) {
        console.log("Success", response);
        trackEvent("payment_success", {
            transactionId: response.TransactionId,
            amount: response.AuthAmount
        });
        window.location.href = "/success?id=" + response.TransactionId;
    },

    OnDecline: function(response) {
        console.log("Declined", response);
        trackEvent("payment_declined", {
            reason: response.ResponseMessage
        });
        showError("Payment declined: " + response.ResponseMessage);
    },

    OnError: function(error) {
        console.error("Error", error);
        trackEvent("payment_error", {error: error});
        showError("An error occurred. Please try again.");
    },

    OnWarn: function(reason) {
        console.warn("Warning", reason);
        trackEvent("payment_warning", {reason: reason});
    },

    // User interaction events
    OnSubmit: function(amount) {
        trackEvent("payment_submit_attempt", {amount: amount});
        if (confirm("Process payment of $" + amount + "?")) {
            paymentWidget.SubmitOk();
        }
    },

    OnCancel: function(detail) {
        trackEvent("payment_cancelled");
        if (confirm("Cancel payment?")) {
            window.location.href = "/checkout";
        }
    },

    OnChangePaymentType: function(paymentType) {
        trackEvent("payment_type_changed", {type: paymentType});
        updateUIForPaymentType(paymentType);
    },

    OnValidation: function({fieldId, validationMessage}) {
        trackEvent("validation_error", {field: fieldId, message: validationMessage});
        displayValidationError(fieldId, validationMessage);
    },

    // Data events
    OnBinLookupResponse: function(detail) {
        trackEvent("bin_lookup", {cardType: detail.lookupResult?.cardType});
        updateCardDisplay(detail);
    },

    OnAmountChanged: function(detail) {
        trackEvent("amount_changed", detail);
        updateAmountDisplay(detail.newAmount);
    },

    OnGetFieldValue: function(values) {
        console.log("Field values retrieved", values);
        handleFieldValues(values);
    },

    // UI events
    OnScrollTop: function(detail) {
        window.scrollTo({top: 0, behavior: 'smooth'});
    },

    OnSize: function({width, height}) {
        console.log("Size changed", width, height);
    },

    OnResponse: function(event) {
        // Log all messages for debugging
        console.debug("Message from iframe:", event.data);
    }
});

Response Object Structure

Success Response (OnSuccess)

{
    "TransactionId": "abc123",
    "AuthAmount": 100.00,
    "ResponseStatus": "TransactionApproved",
    "ResponseMessage": "Approved",
    "ResponseReason": "",
    "PayorId": "12345",          // If payment method was saved
    "SavedPaymentMethodId": "67890"  // If payment method was saved
}

Decline Response (OnDecline)

{
    "ResponseStatus": "TransactionDeclined",
    "ResponseMessage": "Insufficient Funds",
    "ResponseReason": "The card was declined by the issuing bank"
}

BIN Lookup Response (OnBinLookupResponse)

{
    "lookupResult": {
        "cardType": "Visa",
        "issuerName": "Chase Bank",
        "issuerCountry": "US",
        "surcharge": "Allowed"  // or "NotAllowed"
    },
    "surchargeAllowed": true,
    "amountAdjustedTo": 100.00  // Only present if amount was adjusted
}