Payment Envelope Schema
Connect Envelope
{
"version": "1.0", // MUST be 1.0
"payload": "YTc2ZDc2MzEyZ..", // Base64-encoded JSON payload (e.g. Connect Payment)
"pubkey": "c8a6927d0a004..", // Relay Public Key, BIP-340 Schnorr X-only (32 bytes)
"sig": "202d831c6437c..", // Payload Signature, BIP-340 Schnorr (64 bytes)
}
Connect Payment
{
"type": "payment", // MUST be "payment"
"id": "PID-123", // Relay-unique Payment ID
"issued": "2006-01-02T15:04:05-07:00", // RFC 3339 Timestamp
"timeout": 60, // Timeout in seconds, do not pay after this time
"relay": "https://example.com/..", // Payment Relay to submit payment tx
"fee_per_kb": "0.01001386", // Minimum fee per 1000 bytes in payment tx, 8-DP string
"max_size": 10000, // Maximum size in bytes of payment tx
"vendor_icon": "https://example.com/..", // Vendor icon URL, JPG or PNG
"vendor_name": "Vendor Co", // Vendor display name
"vendor_address": "123 Example St", // Vendor business address (optional)
"total": "41.9395", // Total including fees and taxes, 8-DP string
"fees": "1.0", // Fees subtotal, 8-DP string
"taxes": "1.9495", // Taxes subtotal, 8-DP string
"fiat_total": "5.00", // Total in fiat currency, decimal string (optional)
"fiat_tax": "0.23", // Taxes in fiat currency, decimal string (optional)
"fiat_currency": "USD", // ISO 4217 currency code (required with fiat_total/fiat_tax)
"items": [], // List of line items to display (Connect Items)
"outputs": [], // List of outputs to pay (Connect Outputs)
}
Connect Item
{
"type": "item", // item, tax, fee, shipping, discount, donation
"id": "SK-101", // unique item ID or SKU
"icon": "https://example.com/itm/ic.png", // icon URL, JPG or PNG
"name": "Doge Plushie", // name to display
"desc": "One doge plushie in a soft bag", // item description to display
"count": 1, // number of units >= 1
"unit": "38.99", // unit price, 8-DP string
"total": "38.99", // count x unit, 8-DP string
"tax": "1.9495", // tax on this item, 8-DP string (optional)
}
Connect Output
{
"address": "DQ6dt7wCjLDxtdSwCYSAMFHwrD5Q1xybmL", // Dogecoin Address
"amount": "1.0", // Amount, 8-DP string
}
8-DP string
Fields marked 8-DP string
are DECIMAL numbers with up to 8 decimal places,
which represent a Koinu value – the smallest unit of Dogecoin.
They are strings to preserve accuracy; most JSON parsers treat numbers as floating point, which sacrifices some accuracy (e.g. a value of "0.1" cannot be stored accurately as a floating point number.)
These can be parsed using a Decimal library, or code like this.
Payment Envelope Verification
The DogeConnect Payment Envelope contains a Base64-encoded JSON payload, the Payment Relay's public key, and a digital signature of the payload signed by the Payment Relay's private key.
Use the following steps to decode and verify the payload.
- Ensure you verify the
pubkey
hash as described in the Payment QR-Code section. - Decode the Base64-encoded
payload
field, yielding bytes. - Decode the Hex-encoded
pubkey
andsig
fields, yielding bytes. - Compute the Double-SHA256 of the decoded payload bytes from step 2, i.e.
SHA-256(SHA-256(bytes))
- Apply BIP-340
lift_x
algorithm on thepubkey
bytes to recover the full Public Key. A BIP-340 library will supply this step (it's essentially parsing a compressed public key.) - Verify the BIP-340 Schnorr signature, using the Double-SHA256 hash as the
message
, and the full Public Key andsig
. A BIP-340 library will supply the signature verification algorithm. If this step fails, it suggests a MITM attack or faulty implementation. - Parse the JSON payload bytes using a standard JSON parser.
- Check the
timeout
field: do not submit a payment transaction after the timeissued
+timeout
. - Display the payment information and ask the user to confirm payment.
- Create and sign a payment transaction and submit it to the Payment Relay.
The goals of the above process are to verify that the Payment Envelope is cryptographically signed by the Payment Relay's private key, i.e. the envelope was created by the Payment Relay.
A reference implementation of these algorithms exist at github.com/dogeorg/dogeconnect-go which can be packaged for mobile using gomobile bind.