Omise Go Client Library

repository·master·Indexed 41 days ago

https://github.com/omise/omise-go

A Go client library for integrating with the Omise API, enabling merchants to accept payments in Go applications. It provides tools to initialize a client using public and secret keys, execute API operations via the Do() method, and manage payment resources such as Charges, Customers, Cards, and Bank Accounts.

Tokens
16.2K
Snippets
68
Records
72
Agent score
100%

What's inside Omise Go

  1. Implement an EventHandler to process Omise webhooks

    master

    To handle incoming Omise webhook events, you must implement the EventHandler interface or provide an EventHandlerFunc. The handler receives the http.ResponseWriter, the original *http.Request, and a pre-unmarshaled *Event object containing the webhook data.

    You can implement this by creating a struct that satisfies the HandleEvent method, or more simply, by defining a function with the signature func(http.ResponseWriter, *http.Request, *Event) and casting it to EventHandlerFunc.

    // Using EventHandlerFunc for a simple implementation
    myHandler := omise.EventHandlerFunc(func(w http.ResponseWriter, r *http.Request, event *omise.Event) {
        fmt.Printf("Received event: %s\n", event.EventType)
        w.WriteHeader(http.StatusOK)
    })
  2. Initialize an Omise client and create a charge

    master

    To use the library, initialize a client using your Omise Public Key and Secret Key. You can then perform operations like creating a charge using a token (which should be generated on the client-side for security).

    Note: For security and PCI-DSS compliance, card data should not transit through your server. Use client-side libraries to generate tokens first.

    package main
    
    import (
    	"log"
    
    	"github.com/omise/omise-go"
    	"github.com/omise/omise-go/operations"
    )
    
    const (
    	// Read these from environment variables or configuration files!
    	OmisePublicKey = "pkey_test_no1t4tnemucod0e51mo"
    	OmiseSecretKey = "skey_test_no1t4tnemucod0e51mo"
    )
    
    func main() {
    	client, e := omise.NewClient(OmisePublicKey, OmiseSecretKey)
    	if e != nil {
    		log.Fatal(e)
    	}
    
    	/** Retrieve a token from a request
    	 * A token should be created from a client side by using our client-side libraries
    	 * https://docs.omise.co/libraries#client-side-libraries
    	 * More information:
    	 * - https://docs.omise.co/collecting-card-information
    	 * - https://docs.omise.co/security-best-practices
    	**/
    	token := "tokn_test_no1t4tnemucod0e51mo"
    
    	// Creates a charge from the token
    	charge, createCharge := &omise.Charge{}, &operations.CreateCharge{
    		Amount:   100000, // ฿ 1,000.00
    		Currency: "thb",
    		Card:     token,
    	}
    	if e := client.Do(charge, createCharge); e != nil {
    		log.Fatal(e)
    	}
    
    	log.Printf("charge: %s  amount: %s %d\n", charge.ID, charge.Currency, charge.Amount)
    }
  3. Enable debug mode to monitor API responses

    master

    To monitor the response code and body from every API call, call SetDebug(true) on your client instance immediately after initialization.

    client, e := omise.NewClient(OmisePublicKey, OmiseSecretKey)
    if e != nil {
    	log.Fatal(e)
    }
    
    // Enabling debug mode to monitor response from API call
    client.SetDebug(true)
  4. Set the Omise API version

    master

    You can specify a specific Omise API version on the client instance. This setting takes priority over the version configured in your Omise Dashboard, which is useful for managing different environments (e.g., using a newer version in development and an older version in production).

    client.APIVersion = "2015-11-06"
  5. Override API Endpoints

    master

    The Client struct exposes an Endpoints field, which is a map[internal.Endpoint]string. You can use this to override the default URL for specific API endpoints. This is useful for pointing the client to a mock server or a different environment.

    client.Endpoints[someEndpointKey] = "https://custom-api.example.com"
  6. Initialize the Omise Client

    master

    Use NewClient(pkey, skey string) to create a new Client instance. You must provide your Omise public key (pkey) and secret key (skey). These keys can be obtained from the Omise Dashboard.

    The Client manages HTTP operations against the Omise REST API and should be used in conjunction with operation structures from the operations subpackage.

    import "github.com/omise/omise-go"
    
    client, err := omise.NewClient("pkey_test_...", "skey_test_...")
    if err != nil {
        // handle error
    }
  7. Execute API operations with different credentials using DoWithKeys()

    master

    In multi-tenant scenarios where you need to use different credentials for different requests while reusing the same underlying http.Client, use DoWithKeys(result interface{}, pkey, skey string, operation internal.Operation).

    Concurrency Warning: DoWithKeys is safe to call from multiple goroutines sharing the same Client instance. However, you must treat the Client configuration (context, custom headers, user agent, and endpoint settings) as immutable once the client is shared. Do not call configuration methods like WithCustomHeaders or WithContext while the client is being used concurrently, as this causes data races.

    var result MyResponseStruct
    // Use specific keys for this request without changing the client's global state
    err := client.DoWithKeys(&result, "pkey_tenant_a", "skey_tenant_a", operation)
  8. Use the Event type to handle Omise webhooks and events

    master

    The Event type represents an Omise event object. Because the Data field in an Omise event can contain different resource types (e.g., a Charge, Customer, or Card) depending on the event type, the Event struct implements a custom UnmarshalJSON method.

    When you unmarshal JSON into an Event struct, the library automatically inspects the event data to determine the correct concrete type for the Data field. This allows you to type-assert the Data field to the specific resource type you expect.

    Key Fields:

    • Key: The unique identifier for the event.
    • Data: An interface{} that will contain the actual resource object (e.g., *Charge, *Customer, etc.) after unmarshaling.
    // Example of handling an unmarshaled Event
    var event omise.Event
    err := json.Unmarshal(jsonData, &event)
    if err != nil {
    	return err
    }
    
    // Use a type switch or assertion to access the specific resource in Data
    switch data := event.Data.(type) {
    case *omise.Charge:
    	fmt.Printf("Charge ID: %s\n", data.ID)
    case *omise.Customer:
    	fmt.Printf("Customer Email: %s\n", data.Email)
    case *omise.Deletion:
    	fmt.Printf("Resource was deleted\n")
    }
  9. Handle Omise REST API errors

    master

    When an API call fails, the library may return an *Error struct. This struct contains details returned by Omise's REST API. You can inspect the Code or StatusCode fields to implement specific error handling logic for different failure scenarios (e.g., authentication failures, validation errors, or rate limiting).

    // Example of checking for a specific API error code
    err := client.Charge(params)
    if err != nil {
    	if apiErr, ok := err.(*omise.Error); ok {
    		if apiErr.Code == "card_declined" {
    			// Handle declined card specifically
    		}
    	}
    }
  10. Find a specific resource within a List type

    master

    The Omise Go library provides various List types (e.g., AccountList, ChargeList, CustomerList) that represent paginated responses from the Omise REST API. Each list type includes a Find(id string) method. This method iterates through the Data slice and returns the resource with the matching ID. If no resource with the provided ID is found within that specific list, the method returns nil.

    // Example usage pattern (conceptual)
    // Assuming 'chargeList' is an instance of ChargeList retrieved from the API
    charge := chargeList.Find("chrg_test_12345")
    if charge != nil {
        // Use the charge object
    }
  11. Execute API operations with Do()

    master

    The Do(result interface{}, operation internal.Operation) method is the primary way to perform API requests. It executes the provided operation and unmarshals the JSON response into the result parameter.

    If the operation is successful, result will contain the response data. If it fails, a non-nil error is returned, which may be of type *omise.Error. You can inspect the Code and Message fields of the error for more details.

    // Example usage with an operation (assuming 'operation' is defined elsewhere)
    var result MyResponseStruct
    err := client.Do(&result, operation)
    if err != nil {
        // handle error
    }