Skip to content

RequestToReceiveBill + AdditionalFeePayment support in OCP #199

@kid42

Description

@kid42

Summary

Requesting the re-introduction of merchant-initiated payment support in the OCP stack — specifically RequestToReceiveBill with AdditionalFeePayment support — to enable third-party payment processors to build merchant checkout experiences for Flipcash currencies.

Background

The original Code Wallet SDK had a fully functional merchant payment flow:

  • RequestPayment (Kind=2) and RequestPaymentWithFeesSupport (Kind=4) payload types
  • RequestToReceiveBill message with requestorAccount, exchangeData, and additionalFees
  • AdditionalFeePayment allowing third-party integrators to route a percentage (in basis points) to their own destination address
  • The server handled atomic fee splitting — merchant gets paid, integrator gets their cut, all in one intent

This enabled third parties to build merchant payment integrations where:

  1. Merchant displays a Kikcode with an amount
  2. Customer scans with their wallet app, sees "Pay $X.XX?", confirms
  3. Payment settles on-chain with fees routed atomically

Current State

In the OCP migration, this entire flow was removed:

  • Proto (ocp-protobuf-api): Only RequestToGiveBill and RequestToGrabBill exist. No RequestToReceiveBill, no AdditionalFeePayment.
  • Server (ocp-server): SendMessage only handles Message_RequestToGrabBill and Message_RequestToGiveBill. Any other message type returns InvalidArgument.
  • iOS App (code-ios-app): CashCode.Payload only supports Kind.cash (0) and Kind.cashMulticurrency (1). ScanViewModel only routes to ScanCashOperation (receive cash from sender). No scan handler exists for merchant payment requests. Deep links only support /cash, /token, /login, /verify — no /pay route.

The current protocol only supports peer-to-peer "give cash" (sender → receiver). There is no mechanism for a merchant to request payment from a customer.

Why This Matters

Flipcash has created an exciting ecosystem where anyone can launch a community currency. But for these currencies to have real utility beyond speculation and social tipping, they need to be spendable at merchants.

Every community currency creator would benefit from merchant adoption — it gives their token real-world purchasing power. But no individual currency creator should have to build payment infrastructure. That should come from third-party integrators (like how Stripe/Square handle payments for USD, not the Federal Reserve).

Without merchant payment support in the protocol, third parties cannot build payment integrations for Flipcash currencies — no checkout flows, no invoicing, no merchant acceptance.

Proposed Changes

1. Proto (ocp-protobuf-api)

Add to messaging_service.proto:

message RequestToReceiveBill {
    common.v1.SolanaAccountId requestor_account = 1 [(validate.rules).message.required = true];
    
    oneof exchange_data {
        transaction.v1.ExchangeData exact = 2;
        transaction.v1.ExchangeDataWithoutRate partial = 3;
    }
    
    repeated AdditionalFeePayment additional_fees = 4;
}

message AdditionalFeePayment {
    common.v1.SolanaAccountId destination = 1 [(validate.rules).message.required = true];
    uint32 fee_bps = 2 [(validate.rules).uint32 = {gte: 1, lte: 5000}];
}

Add to the Message oneof:

message Message {
    // ... existing fields ...
    oneof kind {
        RequestToGrabBill request_to_grab_bill = 3;
        RequestToGiveBill request_to_give_bill = 4;
        RequestToReceiveBill request_to_receive_bill = 6; // next available field number
    }
}

2. Server (ocp-server)

  • Add RequestToReceiveBillMessageHandler to validate the message (verify requestor account, validate fee bounds)
  • Register it in SendMessage's switch statement
  • Handle fee routing in SubmitIntent for the corresponding payment intent type

3. iOS App (code-ios-app)

  • Add Kind.requestPayment (or similar) to CashCode.Payload
  • Add a PayMerchantOperation (mirror of ScanCashOperation but where the scanner/customer initiates the transfer instead of the advertiser)
  • Handle the new kind in ScanViewModel.didScan
  • Show a confirmation screen: "Pay $X.XX to merchant? [Confirm] [Cancel]"

4. Payload Format

Add a new payload kind for the Kikcode (e.g., Kind=2 for requestPayment) so the app can distinguish "someone wants to give me cash" from "a merchant is requesting payment from me." The existing 20-byte payload format can accommodate this — only byte 0 (kind) changes.

Willingness to Contribute

I'm happy to contribute PRs for any or all of these changes. Would love to discuss the approach and get alignment before writing code.


Related code references:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions