Skip to content

Commit

Permalink
Feature docks, invoice messages, edit store example (#8)
Browse files Browse the repository at this point in the history
* feat: add edit store example

* feat: add invoice messages

* feat: docs
  • Loading branch information
dearjohndoe authored May 20, 2023
1 parent 627337b commit d967bcc
Show file tree
Hide file tree
Showing 6 changed files with 388 additions and 0 deletions.
8 changes: 8 additions & 0 deletions docs/Getting started.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Getting started

## Installation
To add the dependency, use the following command:
`go get github.com/TheTonpay/tonpay-go-sdk`

## Examples
For usage examples, refer to the [examples](https://github.com/TheTonpay/tonpay-go-sdk/tree/main/examples) directory.
26 changes: 26 additions & 0 deletions docs/Initialization.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Initialization

Before starting to use the SDK, you need to prepare the environment. The **tonpay-go-sdk** relies on [tonutils-go](https://github.com/xssnick/tonutils-go) for interacting with the TON Blockchain. To initialize the necessary objects, follow these steps:
```
// First of all, we need to create connection pool
client := liteclient.NewConnectionPool()
// Choose testnet or mainnet
configUrl := "https://ton-blockchain.github.io/global.config.json" // mainnet
// configUrl := "https://ton-blockchain.github.io/testnet-global.config.json" // testnet
err := client.AddConnectionsFromConfigUrl(context.Background(), configUrl)
if err != nil {
log.Println(err)
return false
}
api := ton.NewAPIClient(client)
// Get block
block, err := api.CurrentMasterchainInfo(context.Background())
if err != nil {
log.Println(err)
return false
}
```
Make sure to update the `configURL` based on whether you want to connect to the mainnet or testnet.
90 changes: 90 additions & 0 deletions docs/Interacting with invoice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Interacting with invoice

When working with the store, you had a chance to get the invoice. Here you'll learn what you can do with it.

## Edit an invoice
To edit an invoice, you can follow the same formula as before:
1. Connect the owner's wallet using the seed phrases:
```
words := strings.Split("seed phrase ...", " ")
// Wallet version you can find in explorer, for example on tonscan: https://tonscan.org/address/<wallet_address>
w, err := wallet.FromSeed(api, words, wallet.V4R2)
if err != nil {
panic(err)
}
```
2. Build the message cell:
```
editInvoiceMessage, err := tonpaygo.EditInvoiceMessage(false, "", "testid", "", 700000000)
if err != nil {
panic(err)
}
```
3. Send an internal message with the cell (ensure that the fee is `EditInvoiceFee`):
```
message := wallet.Message{
Mode: 1,
InternalMessage: &tlb.InternalMessage{
Bounce: true,
DstAddr: addr,
Amount: tlb.FromNanoTONU(tonpaygo.EditInvoiceFee),
Body: editInvoiceMessage,
},
}
err = w.Send(context.Background(), &message, true)
if err != nil {
panic(err)
}
```
**Warning:** Only the merchant can edit the invoice. It's important to note that an invoice cannot be edited once it has been paid or if it is inactive.

## Manage active status
To manage the active status of an invoice, you can use the following steps:
```
activateInvoiceMessage, err := tonpaygo.ActivateInvoiceMessage()
// or
deactivateInvoiceMessage, err := tonpaygo.DeactivateInvoiceMessage()
// Then do step 3(send message) from previous example
```
After confirming the transaction, the invoice will be activated/deactivated.

**Warning:** Only the merchant can activate or deactivate the invoice. It's important to note that when the invoice is deactivated, it will not accept any payments and cannot be edited.

## Paying the invoice
After the invoice is issued, the customer can make the payment in two ways:
1. Provide the customer with the payment link. You can find an example of this method in the [create-and-pay-invoice-url](https://github.com/TheTonpay/tonpay-go-sdk/tree/main/examples/create-and-pay-invoice-url) example.
2. Send a payment to the invoice programmatically. To do this, you can use the following steps:

a. Get the payment message using `tonpaygo.PayInvoiceMessage()`.
```
message := wallet.Message{
...
InternalMessage: &tlb.InternalMessage{
...
Amount: invoiceAmount + tlb.FromNanoTONU(tonpaygo.ActiveInvoiceFee),
},
}
```
b. Send the payment message using the same process as mentioned before.

## Get invoice info
Like in example below you can get other contract data:
```
func GetStore(api *ton.APIClient, block *ton.BlockIDExt, addr *address.Address) (*address.Address, error)
func GetMerchant(api *ton.APIClient, block *ton.BlockIDExt, addr *address.Address) (*address.Address, error)
func GetCustomer(api *ton.APIClient, block *ton.BlockIDExt, addr *address.Address) (*address.Address, error)
func HasCustomer(api *ton.APIClient, block *ton.BlockIDExt, addr *address.Address) (bool, error)
func GetInvoiceID(api *ton.APIClient, block *ton.BlockIDExt, addr *address.Address) (string, error)
func GetInvoiceMetadata(api *ton.APIClient, block *ton.BlockIDExt, addr *address.Address) (string, error)
func GetAmount(api *ton.APIClient, block *ton.BlockIDExt, addr *address.Address) (uint64, error)
func IsPaid(api *ton.APIClient, block *ton.BlockIDExt, addr *address.Address) (bool, error)
func IsActive(api *ton.APIClient, block *ton.BlockIDExt, addr *address.Address) (bool, error)
func GetInvoiceVersion(api *ton.APIClient, block *ton.BlockIDExt, addr *address.Address) (uint64, error)
```
Or get all in one:
```
func GetInvoiceData(api *ton.APIClient, block *ton.BlockIDExt, addr *address.Address) (InvoiceData, error)
```
117 changes: 117 additions & 0 deletions docs/Interacting with store.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@

# Interacting with Store

Congratulations on initializing the SDK! Now let's move on to interacting with stores.

## Getting a store

To start interacting with a store, you need to obtain the Store instance. To do that, you'll need the store ID, which can be found on your [store page](https://business.thetonpay.app/stores) in the [merchant portal](https://business.thetonpay.app/). Click the "COPY ID" button to obtain the store ID.

![enter image description here](https://tonbyte.com/gateway/3A3420357AA219F7487DEDFB1F031A04CD9392073D8B2D9B54F34BDE06772D60/Screenshot_20230421_184454.png)

Let's assume that our store ID is `EQCtRWrkfxovf-H02xc5CjHpC4t3VnxAIrCg6LJaaYflj4RY`. Add the following code after the initialization:
```
storeAddress := "EQCPibUxBk7xwwcKBja6SbC5Pm1BCihGDA6SY5wTmFhrmYSh"
storeOwner, err := tonpaygo.GetOwner(api, block, storeAddress)
if err != nil {
fmt.Println(err)
return false
}
fmt.Printf(storeName)
```
Congratulations! You have now retrieved the store owner's address directly from the Blockchain contract.

## Edit store
To edit store data, you need to follow these three steps:
1. Connect the owner's wallet using the seed phrases:
```
words := strings.Split("seed phrase ...", " ")
// Wallet version you can find in explorer, for example on tonscan: https://tonscan.org/address/<wallet_address>
w, err := wallet.FromSeed(api, words, wallet.V4R2)
if err != nil {
panic(err)
}
```
2. Build the message cell:
```
editStoreCell, err := tonpaygo.EditStoreMessage("Durger King 3.0", "Fast food", "7E5D1FDEA9EEC531F3E6BAA69E22615FB4CEA111BAE40219AB4E60053489DD64", "", 541)
if err != nil {
panic(err)
}
```
3. Send an internal message with the cell:
```
message := wallet.Message{
Mode: 1,
InternalMessage: &tlb.InternalMessage{
Bounce: true,
DstAddr: addr,
Amount: tlb.FromNanoTONU(tonpaygo.EditStoreFee),
Body: editStoreCell,
},
}
err = w.Send(context.Background(), &message, true)
if err != nil {
panic(err)
}
```
**Note:** Make sure to replace "seed phrase ..." with the actual seed phrases of the owner's wallet.

## Create invoice
To create an invoice, there are two methods available:

1. Create a cell that stores all the required information about the payment, predicts the future invoice contract address, and packs it into a URL. You can find an example of this method [here](https://github.com/TheTonpay/tonpay-go-sdk/tree/main/examples/create-and-pay-invoice-url). This method doesn't require the store wallet seeds on the backend.

2. Deploy the invoice contract from the backend and send its address to the customer. First, retrieve the wallet from the previous section, "Edit store":
```
words := strings.Split("seed phrase ...", " ")
// Wallet version you can find in explorer, for example on tonscan: https://tonscan.org/address/<wallet_address>
w, err := wallet.FromSeed(api, words, wallet.V4R2)
if err != nil {
panic(err)
}
```
Then, build and send the message (ensure that you double-check the fee you send):
```
createIssueStoreCell, err := tonpaygo.IssueInvoiceMessage(nil, false, "Invoice from go", "", tlb.MustFromTON("1").NanoTON().Uint64())
if err != nil {
panic(err)
}
message := wallet.Message{
Mode: 1,
InternalMessage: &tlb.InternalMessage{
Bounce: true,
DstAddr: addr,
Amount: tlb.FromNanoTONU(tonpaygo.IssueInvoiceFee),
Body: createIssueStoreCell,
},
}
err = w.Send(context.Background(), &message, true)
if err != nil {
panic(err)
}
```


## Get store info
Like in example below you can get other contract data:
```
func GetOwner(api *ton.APIClient, block *ton.BlockIDExt, addr *address.Address) (*address.Address, error)
func GetName(api *ton.APIClient, block *ton.BlockIDExt, addr *address.Address) (string, error)
func GetDescription(api *ton.APIClient, block *ton.BlockIDExt, addr *address.Address) (string, error)
func GetImage(api *ton.APIClient, block *ton.BlockIDExt, addr *address.Address) (string, error)
func GetStoreWebhook(api *ton.APIClient, block *ton.BlockIDExt, addr *address.Address) (string, error)
func GetMccCode(api *ton.APIClient, block *ton.BlockIDExt, addr *address.Address) (int64, error)
func GetIsActive(api *ton.APIClient, block *ton.BlockIDExt, addr *address.Address) (bool, error)
func GetStoreVersion(api *ton.APIClient, block *ton.BlockIDExt, addr *address.Address) (uint64, error)
```
Or get all in one:
```
func GetStoreData(api *ton.APIClient, block *ton.BlockIDExt, addr *address.Address) (StoreData, error)
```
68 changes: 68 additions & 0 deletions examples/edit-store/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package main

import (
"context"
"fmt"
"log"
"strings"

tonpaygo "github.com/TheTonpay/tonpay-go-sdk/src"
"github.com/xssnick/tonutils-go/address"
"github.com/xssnick/tonutils-go/liteclient"
"github.com/xssnick/tonutils-go/tlb"
"github.com/xssnick/tonutils-go/ton"
"github.com/xssnick/tonutils-go/ton/wallet"
)

func EditStore(addr *address.Address, version wallet.Version, seedWords []string) bool {
client := liteclient.NewConnectionPool()

// Choose testnet or mainnet
configUrl := "https://ton-blockchain.github.io/global.config.json" // mainnet
// configUrl := "https://ton-blockchain.github.io/testnet-global.config.json" // testnet
err := client.AddConnectionsFromConfigUrl(context.Background(), configUrl)
if err != nil {
log.Println(err)
return false
}

api := ton.NewAPIClient(client)

editStoreCell, err := tonpaygo.EditStoreMessage("Durger King 3.1", "Fast food", "7E5D1FDEA9EEC531F3E6BAA69E22615FB4CEA111BAE40219AB4E60053489DD64", "", 541)
if err != nil {
fmt.Println(err)
return false
}

w, err := wallet.FromSeed(api, seedWords, wallet.V4R2)
if err != nil {
fmt.Println(err)
return false
}

message := wallet.Message{
Mode: 1,
InternalMessage: &tlb.InternalMessage{
Bounce: true,
DstAddr: addr,
Amount: tlb.FromNanoTONU(tonpaygo.EditStoreFee),
Body: editStoreCell,
},
}

err = w.Send(context.Background(), &message, true)
if err != nil {
fmt.Println(err)
return false
}

return true
}

func main() {
storeAddr := address.MustParseAddr("EQBOPmMoxApwWAUW77ou70qOqqlDjCZLdqbdo6xRm3tUxP_7")
walletVersion := wallet.V4R2
seedWords := strings.Split("seed words here ...", " ")
isUpdated := EditStore(storeAddr, walletVersion, seedWords)
fmt.Println("isUpdated:", isUpdated)
}
Loading

0 comments on commit d967bcc

Please sign in to comment.