code-payments / code-payments/ocp-server

RequestToReceiveBill + AdditionalFeePayment support in OCP

Open
#199 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
1
Forks
2
Avg merge
9h 30m
Merged PRs (30d)
20

Description

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:

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with messaging_service.proto, ocp/rpc/messaging/message_handler.go, and ocp/rpc/messaging/server.go to compare the existing bill message flow with the proposed receive-bill path. Then review ScanViewModel.swift and SendCashOperation.swift alongside the referenced SDK payment files. Done means the protocol, server fee routing, and iOS merchant-payment flow are aligned and support confirmation before settlement.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, swift
Domain
api, backend, mobile, payments
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.