# Submit payment

## POST /v1/transactions/payment

>

```json
{"openapi":"3.1.0","info":{"title":"om-api-rest","version":"0.1.0"},"tags":[{"name":"transactions","description":"Transactions API"}],"servers":[{"url":"https://api.testnet.1money.network","description":"Testnet API server"},{"url":"https://api.1money.network","description":"Mainnet API server"},{"url":"http://localhost:18555","description":"Local API server"}],"paths":{"/v1/transactions/payment":{"post":{"tags":["transactions"],"operationId":"payment","requestBody":{"description":"transaction request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentTransactionRequest"}}},"required":true},"responses":{"200":{"description":"","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Hash"}}}},"400":{"description":"Client error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RESTErrorData"}}}},"404":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RESTErrorData"}}}},"408":{"description":"Request timeout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RESTErrorData"}}}},"422":{"description":"Business logic error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RESTErrorData"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RESTErrorData"}}}}}}}},"components":{"schemas":{"PaymentTransactionRequest":{"allOf":[{"$ref":"#/components/schemas/PaymentPayload"},{"type":"object","required":["signature"],"properties":{"signature":{"$ref":"#/components/schemas/RestSignature","description":"The signature of the transaction."}}}],"description":"Represents token transfer transaction requests to/from REST."},"PaymentPayload":{"type":"object","required":["chain_id","nonce","recipient","value","token"],"properties":{"chain_id":{"type":"integer","format":"int64","description":"The chain id of the transaction.","minimum":0},"nonce":{"type":"integer","format":"int64","description":"The nonce of the transaction.","minimum":0},"recipient":{"$ref":"#/components/schemas/AddressSchema","description":"The destination address of the transaction."},"token":{"$ref":"#/components/schemas/TokenAddressSchema","description":"The token address of the transaction."},"value":{"$ref":"#/components/schemas/U256Schema","description":"The token value of the transaction to be transferred."}}},"AddressSchema":{"type":"string","title":"string"},"TokenAddressSchema":{"type":"string","title":"string"},"U256Schema":{"type":"string","title":"string"},"RestSignature":{"type":"object","description":"Signature type for REST requests.\n\nWe use this type to avoid the ambiguity of the signature type in the core\nprimitives.\n\nThis type is referred to `https://github.com/alloy-rs/alloy/blob/b2278c40b2693908e4e5108d65ade26e8d716765/crates/rpc-types-eth/src/transaction/signature.rs#L9`.","required":["r","s","v"],"properties":{"r":{"$ref":"#/components/schemas/SignatureRSchema","description":"The R field of the signature; the point on the curve."},"s":{"$ref":"#/components/schemas/SignatureSSchema","description":"The S field of the signature; the point on the curve."},"v":{"type":"integer","format":"int64","description":"For EIP-155, EIP-2930 and Blob transactions this is set to the parity (0\nfor even, 1 for odd) of the y-value of the secp256k1 signature.\n\nFor legacy transactions, this is the recovery id\n\nSee also <https://ethereum.github.io/execution-apis/api-documentation/> and <https://ethereum.org/en/developers/docs/apis/json-rpc/#eth_gettransactionbyhash>","minimum":0}}},"SignatureRSchema":{"type":"string","title":"string","description":"Signature R schema"},"SignatureSSchema":{"type":"string","title":"string","description":"Signature S schema"},"Hash":{"type":"object","description":"Represents a transaction hash returned by the API.","required":["hash"],"properties":{"hash":{"$ref":"#/components/schemas/B256Schema"}}},"B256Schema":{"type":"string","title":"string"},"RESTErrorData":{"type":"object","required":["error_code","message"],"properties":{"error_code":{"type":"string","description":"Structured error code for programmatic handling"},"message":{"type":"string","description":"Human-readable error message"}}}}}}
```

{% hint style="success" %}
The following code segment demonstrates a Golang implementation for transaction submission.
{% endhint %}

```go
import (
	"fmt"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/crypto"
	"github.com/ethereum/go-ethereum/rlp"
	"math/big"
)

var privateKey = "01833a126ec45d0191519748146b9e35647aab7fed28de1c8e17824970f964a3"

type PaymentPayload struct {
	RecentCheckpoint uint64         `json:"recent_checkpoint"`
	ChainID          uint64         `json:"chain_id"`
	Nonce            uint64         `json:"nonce"`
	Recipient        common.Address `json:"recipient"`
	Value            *big.Int       `json:"value"`
	Token            common.Address `json:"token"`
}

type PaymentRequest struct {
	PaymentPayload
	Signature Signature `json:"signature"`
}

type Signature struct {
	R string
	S string
	V uint64
}

func SignMessage(msg *PaymentMessage) (*Signature, error) {
	encoded, err := rlp.EncodeToBytes(msg)
	if err != nil {
		return nil, err
	}
	hash := crypto.Keccak256(encoded)
	fmt.Printf("Signature Hash: %s\n", common.BytesToHash(hash))
	key, err := crypto.HexToECDSA(privateKey)
	if err != nil {
		return nil, err
	}
	sign, err := crypto.Sign(hash, key)
	if err != nil {
		return nil, err
	}
	fmt.Printf("Signature: 0x%x\n", sign)
	fmt.Printf("Raw bytes: %v\n", sign)
	r := sign[:32]
	s := sign[32:64]
	v := sign[64]
	return &Signature{
		R: common.BytesToHash(r).Hex(),
		S: common.BytesToHash(s).Hex(),
		V: uint64(v),
	}, nil
}

func main() {
	tokenAddr := common.HexToAddress("0x2045a425D0e131E747f8be2F044413733e412d7d")
	payment := &PaymentMessage{
		RecentCheckpoint: 	100,
		ChainID: 		big.NewInt(1212101),
		Nonce:   		0,
		To:      		common.HexToAddress("0x937b9aff6404141681cbf39301aeb869500bbdf0"),
		Value:   		big.NewInt(1),
		Token:   		&tokenAddr,
	}
	signature, err := SignMessage(payment)
	if err != nil {
		panic(fmt.Sprintf("sign payment msg error: %v", err))
	}
	fmt.Printf("Payment msg Signature: %v\n", signature)
}
```
