Univapay Integration: Project Summary & Implementation Plan

1. Project Summary

The goal of this project is to integrate Univapay as a primary payment provider alongside Stripe and PayPal. Univapay is specifically chosen for its robust support for the Japanese market (PayPay, Bank Transfers, Convenience Store payments) and its specialized risk management for digital content businesses.

Key Objectives:

  • Multi-Tenant Support: Allow individual suppliers (users) to connect their own Univapay accounts to receive payments.
  • Diverse Payment Methods: Enable Credit Cards, PayPay, and Bank Transfers for customers.
  • Automated Payouts: Leverage Univapay’s Platform solution to handle fee-splitting (Platform Fee) and automated payouts to suppliers.

2. Architectural Overview

The integration follows the existing “Provider-Interactor” pattern used for Stripe and PayPal.

  • Backend (Laravel): A new UnivapayPlatform trait will be added to the common package to wrap Univapay SDK calls. Interactors in the customer and user domains will handle specific business logic.
  • Frontend (Next.js): The Supplier dashboard will be updated for account onboarding, and the Customer checkout will integrate the Univapay Widget.
  • Async Processing: A robust Webhook system will handle asynchronous payment confirmations (important for PayPay and Bank Transfers).

3. Implementation Plan (3-4 Weeks)

Phase 1: Foundation & Backend Setup (4 Days)

  1. SDK Integration: Add univapay/univapay-php to yoyacoo_be/common/composer.json.
  2. Configuration: Define Univapay Platform keys in .env and config/services.php.
  3. Database Migration:
    • Create user_payment_univapays table to store store_id, api_key, and charges_enabled.
    • Add univapay_transaction_id to the orders table.
  4. Core Trait: Implement ReserveApp\Common\Base\Traits\UnivapayPlatform with methods for:
    • createStoreToken() (for onboarding)
    • createCharge()
    • refundCharge()

Phase 2: Supplier Onboarding (5 Days)

  1. Onboarding Interactor: Create ConnectUnivapayInteractor to handle the OAuth/Token exchange.
  2. Settings UI: Update yoyacoo_fe/supplier/src/pages/accounts/payment_methods to include a “Connect Univapay” button.
  3. Status Sync: Logic to verify if the connected store is “Active” and “Ready for Charges.”

Phase 3: Customer Checkout & Fulfillment (7 Days)

  1. Payment Selection: Update the reservation flow to offer Univapay methods.
  2. Widget Integration: Embed https://widget.univapay.com/client/checkout.js in the customer frontend.
  3. Payment Interactor: Create UnivapayInteractor in yoyacoo_be/customer to:
    • Initiate the charge request.
    • Handle “Requires Action” (e.g., redirecting to PayPay app).
  4. Webhook Handler: Create UnivapayWebhookController to process charge.updated and charge.finished events.

Phase 4: Testing & Hardening (4 Days)

  1. Sandbox Validation: Test Credit Card (Success/Fail), PayPay (Redirect/Return), and Bank Transfer (Pending/Success).
  2. Error Handling: Robust logging for API failures and automated email alerts for failed webhooks.
  3. Documentation: Update API docs and internal “Admin” guide for managing Univapay disputes.

4. Technical Implementation Details

Backend: Univapay Trait (Mockup)

namespace ReserveApp\Common\Base\Traits;

trait UnivapayPlatform {
    public function createCharge(int $amount, array $params) {
        // 1. Calculate Platform Fee using PlatformFeeCal trait
        // 2. Call Univapay SDK to create a Charge with 'transfer_to' the supplier
        // 3. Return the Client Secret for the Frontend Widget
    }
}

Frontend: Widget Integration (Mockup)

const UnivapayWidget = ({ amount, appId }) => {
  return (
    <span
      data-app-id={appId}
      data-checkout="payment"
      data-amount={amount}
      data-currency="jpy"
      data-inline="true"
      data-payment-types="card,paypay,online_banking"
    ></span>
  );
};

5. Security & Compliance

  • PCI DSS: All card data is handled by Univapay’s secure servers; our system only stores non-sensitive “Transaction IDs” and “Masked Card Info” (e.g., **** 1234).
  • Webhooks: All incoming webhooks must be verified using the Univapay-Signature header to prevent spoofing.
  • Permissions: Only authorized Suppliers can access their Univapay credential settings.