Sure! Here's a translation of the guide on how to integrate imsafu using Go:
How to Integrate imsafu with Go
imsafu is a payment processing service that allows you to create and query payments. This document will guide you through accessing the imsafu service.
Prerequisites
Before you begin, make sure you have the following prerequisites:
- Go programming language installed on your computer.
- Go development environment set up.
Install Dependencies
Accessing the imsafu service doesn't require specific dependencies. Here are some default libraries provided, and you can choose the appropriate ones as needed.
Run the following command to install the dependencies:
go get github.com/go-resty/resty/v2
go get github.com/go-playground/validator/v10
Import Required Modules
In your Go file, import the required modules. Add the following import statements at the top of your file:
import (
"fmt"
"net/http"
"encoding/json"
"github.com/go-resty/resty/v2"
"github.com/go-playground/validator/v10"
)
Create Required imsafu Variables
To connect to the imsafu test server, you can use the following variables. If you want to connect to the production server, join the waitlist to obtain the relevant information.
type Options struct {
URL string `validate:"required"`
API string `validate:"required"`
APISecret string `validate:"required"`
Receiver string `validate:"required"`
MerchantBrand string `validate:"required"`
MerchantRedirectURL string `validate:"required"`
}
func main() {
options := Options{
URL: "https://devnet.imsafu.com",
API: "https://allowpay-api-devnet.fly.dev/v1",
APISecret: "your-api-secret",
Receiver: "your-wallet-account",
MerchantBrand: "imsafu demo",
MerchantRedirectURL: "https://merchant.com/redirect",
}
}
Create a New Payment
First, we need to generate a 32-character hexadecimal string as the ID for a new order.
func createOrderID() string {
str := uuid.Must(uuid.NewRandom()).String()
return fmt.Sprintf("0x%s", strings.Join([]string{strings.Repeat("0", 32-len(str)), str}, ""))
}
To create a new payment, we need to implement a createPayment
method. This method takes the payment amount as a parameter and returns a structure parsed as a PaymentResponse
object.
type Payment struct {
OrderID string `json:"orderID"`
Receiver string `json:"receiver"`
Amount string `json:"amount"`
}
type PaymentResponse struct {
Status string `json:"status"`
Payment Payment `json:"payment"`
}
func createPayment(amount int64, options Options) (*PaymentResponse, error) {
orderID := createOrderID()
paymentResponse := &PaymentResponse{}
payload := struct {
Payment Payment `json:"payment"`
NotifyURL string `json:"notifyURL"`
}{
Payment: Payment{
OrderID: orderID,
Receiver: options.Receiver,
Amount: strconv.FormatInt(amount, 10),
},
NotifyURL: options.URL + "/notify",
}
client := resty.New()
resp, err := client.R().
SetHeader("Content-Type", "application/json").
SetHeader("Authorization", "Bearer " + options.APISecret).
SetBody(payload).
SetResult(&paymentResponse).
Post(options.API + "/depositPay")
if err != nil {
return nil, err
}
return &paymentResponse, nil
}
Generate Payment URL
Next, write a method to generate the payment URL:
func buildPaymentURL(itemMemo string, paymentResponse *PaymentResponse, options Options) string {
paymentURL := fmt.Sprintf("%s/payment_qrcode", options.URL)
url := fmt.Sprintf("%s?payID=%s&brand=%s&memo=%s&redirect_url=%s¤cy=USD",
paymentURL, paymentResponse.Payment.OrderID, options.MerchantBrand, itemMemo, options.MerchantRedirectURL)
return url
}
amount := int64(100)
paymentResponse, err := createPayment(amount, options)
if err != nil {
// Handle error
}
paymentURL := buildPaymentURL("test item", paymentResponse, options)
User Payment
Display the generated paymentURL
to the user, who can click on it to open the payment interface in a web page. For the specific payment process, you can refer to the Using imsafu for Payments guide.
Retrieve Payment Information
After the user completes the payment, imsafu will send a POST
request to the notifyURL
provided during the order creation, containing the payID
. We need to retrieve the payment information through the getPayment
API and confirm if the user's payment was successful.
To retrieve payment information, we need to implement the getPayment
method. This method takes the payment ID (payID
) as a parameter and returns a structure parsed as a PaymentResponse
object.
func getPayment(payID string, options Options) (*PaymentResponse, error) {
client := resty.New()
paymentResponse := &PaymentResponse{}
resp, err := client.R().
SetResult(&paymentResponse).
Get(options.API + "/depositPays/" + payID)
if err != nil {
return nil, err
}
return &paymentResponse, nil
}
// Get payID from the notify request
paymentResponse, err := getPayment(payID, options)
if err != nil {
// Handle error
}
// Perform other operations
Appendix: Type Definitions Used in the Code
type Payment struct {
PayID string `json:"payID"`
OrderID string `json:"orderID"`
Receiver string `json:"receiver"`
Amount string `json:"amount"`
OriginalAmount string `json:"originalAmount"`
MaxFeeAmount string `json:"maxFeeAmount"`
Deadline string `json:"deadline"`
}
type Chain struct {
ID int `json:"id"`
Symbol string `json:"symbol"`
Name string `json:"name"`
}
type Token struct {
Symbol string `json:"symbol"`
Address string `json:"address"`
}
type ReceiveTx struct {
Chain Chain `json:"chain"`
TxID string `json:"txID"`
ConfirmedAt string `json:"confirmedAt"`
Amount string `json:"amount"`
FeeAmount string `json:"feeAmount"`
Token Token
`json:"token"`
}
type Deposit struct {
ChainID int `json:"chainID"`
Token string `json:"token"`
}
type PaymentResponse struct {
Status string `json:"status"`
Payment Payment `json:"payment"`
Owner string `json:"owner"`
DepositAddress string `json:"depositAddress"`
CallID int `json:"callID"`
ReceiveTx *ReceiveTx `json:"receiveTx,omitempty"`
Deposits []Deposit `json:"deposits,omitempty"`
}
Please note that the above code is provided as an example and may need to be modified and adapted according to your specific requirements.