No description
go-paymongo
A Go client library for the PayMongo API.
Installation
go get codeberg.org/mdrinkuth/go-paymongo
Requirements
- Go 1.21+
- A PayMongo account and API keys
Quick Start
packagemainimport("context""fmt""log"paymongo"codeberg.org/mdrinkuth/go-paymongo")funcmain(){client:=paymongo.NewClient("sk_test_xxx","pk_test_xxx")link,err:=client.Links.Create(context.Background(),paymongo.CreateLinkParams{Amount:10000,// PHP 100.00Description:"Order #1234",})iferr!=nil{log.Fatal(err)}fmt.Println(link.Attributes.CheckoutURL)}Authentication
PayMongo uses two API keys — a secret key and a public key. You can find both in your PayMongo Dashboard.
- Secret key (
sk_test_.../sk_live_...) — used for most API calls - Public key (
pk_test_.../pk_live_...) — used for creating sources (GCash, GrabPay)
// Test keysclient:=paymongo.NewClient("sk_test_xxx","pk_test_xxx")// Live keysclient:=paymongo.NewClient("sk_live_xxx","pk_live_xxx")Usage
Payment Links
// Createlink,err:=client.Links.Create(ctx,paymongo.CreateLinkParams{Amount:10000,// PHP 100.00Description:"Order #1234",Remarks:"Thank you for your purchase!",})// Get by IDlink,err:=client.Links.Get(ctx,"link_xxx")// Get by reference numberlink,err:=client.Links.GetByReferenceNumber(ctx,"abc123")// Archivelink,err:=client.Links.Archive(ctx,"link_xxx")// Unarchivelink,err:=client.Links.Unarchive(ctx,"link_xxx")Checkout Sessions
// Createcheckout,err:=client.Checkout.Create(ctx,paymongo.CreateCheckoutParams{Amount:10000,Currency:"PHP",PaymentMethodTypes:[]string{"card","gcash","paymaya"},SuccessURL:"https://yoursite.com/success",CancelURL:"https://yoursite.com/cancel",LineItems:[]paymongo.LineItem{{Name:"T-Shirt",Amount:10000,Currency:"PHP",Quantity:1,},},Billing:&paymongo.Billing{Name:"Juan dela Cruz",Email:"juan@example.com",Phone:"+639171234567",},SendEmailReceipt:true,ShowLineItems:true,})// Getcheckout,err:=client.Checkout.Get(ctx,"cs_xxx")// Expirecheckout,err:=client.Checkout.Expire(ctx,"cs_xxx")Payments
// Getpayment,err:=client.Payments.Get(ctx,"pay_xxx")// Listpayments,err:=client.Payments.List(ctx,paymongo.ListParams{Limit:10,After:"pay_xxx",// cursor — fetch payments after this ID})Refunds
// Create a full refundrefund,err:=client.Refunds.Create(ctx,paymongo.CreateRefundParams{Amount:10000,PaymentID:"pay_xxx",Reason:paymongo.RefundReasonRequestedByCustomer,Notes:"Customer changed their mind",})// Create a partial refundrefund,err:=client.Refunds.Create(ctx,paymongo.CreateRefundParams{Amount:5000,// PHP 50.00 of PHP 100.00PaymentID:"pay_xxx",Reason:paymongo.RefundReasonOthers,})// Getrefund,err:=client.Refunds.Get(ctx,"ref_xxx")// Listrefunds,err:=client.Refunds.List(ctx,paymongo.ListParams{Limit:10})Sources (GCash, GrabPay, QRPh)
// Create a GCash sourcesource,err:=client.Sources.Create(ctx,paymongo.CreateSourceParams{Amount:10000,Currency:"PHP",Type:paymongo.SourceTypeGCash,Redirect:paymongo.Redirect{Success:"https://yoursite.com/success",Failed:"https://yoursite.com/failed",},})// Redirect the user to complete paymentfmt.Println(source.Attributes.Redirect.CheckoutURL)// Get (poll for status updates)source,err=client.Sources.Get(ctx,source.ID)switchsource.Attributes.Status{casepaymongo.SourceStatusChargeable:fmt.Println("Ready to charge!")casepaymongo.SourceStatusConsumed:fmt.Println("Already consumed")casepaymongo.SourceStatusFailed:fmt.Println("Payment failed")}Note: After creating a source, redirect the user to
source.Attributes.Redirect.CheckoutURL. Use webhooks to listen for thesource.chargeableevent rather than relying solely on polling.
Webhooks
// Createwebhook,err:=client.Webhooks.Create(ctx,paymongo.CreateWebhookParams{URL:"https://yoursite.com/webhooks/paymongo",Events:[]paymongo.WebhookEvent{paymongo.EventPaymentPaid,paymongo.EventPaymentFailed,paymongo.EventSourceChargeable,},})// Important: save webhook.Attributes.SecretKey — you'll need it to verify signaturesfmt.Println(webhook.Attributes.SecretKey)// Listwebhooks,err:=client.Webhooks.List(ctx)// Getwebhook,err=client.Webhooks.Get(ctx,"hook_xxx")// Updatewebhook,err=client.Webhooks.Update(ctx,"hook_xxx",paymongo.UpdateWebhookParams{URL:"https://yoursite.com/webhooks/paymongo-v2",Events:[]paymongo.WebhookEvent{paymongo.EventPaymentPaid,},})// Enable / Disablewebhook,err=client.Webhooks.Enable(ctx,"hook_xxx")webhook,err=client.Webhooks.Disable(ctx,"hook_xxx")Verifying webhook signatures
funchandleWebhook(whttp.ResponseWriter,r*http.Request){payload,err:=io.ReadAll(r.Body)iferr!=nil{http.Error(w,"failed to read body",http.StatusBadRequest)return}sigHeader:=r.Header.Get("Paymongo-Signature")webhookSecret:="whsec_xxx"// from webhook.Attributes.SecretKeyclient:=paymongo.NewClient("sk_test_xxx","pk_test_xxx")iferr:=client.Webhooks.VerifySignature(payload,sigHeader,webhookSecret);err!=nil{http.Error(w,"invalid signature",http.StatusUnauthorized)return}// Signature is valid — process the eventw.WriteHeader(http.StatusOK)}Error Handling
All API errors are returned as *paymongo.ErrorResponse:
link,err:=client.Links.Get(ctx,"link_nonexistent")iferr!=nil{varpmErr*paymongo.ErrorResponseiferrors.As(err,&pmErr){fmt.Println(pmErr.StatusCode)// 404fmt.Println(pmErr.Errors[0].Code)// "resource_not_found"fmt.Println(pmErr.Errors[0].Detail)// "The resource you were looking for does not exist."}}Amounts
All amounts are in centavos:
| PHP Amount | Centavos |
|---|---|
| PHP 1.00 | 100 |
| PHP 100.00 | 10000 |
| PHP 1,000.00 | 100000 |
Advanced
Custom HTTP client
httpClient:=&http.Client{Timeout:60*time.Second,Transport:&http.Transport{MaxIdleConns:10,},}client:=paymongo.NewClient("sk_test_xxx","pk_test_xxx",paymongo.WithHTTPClient(httpClient),)Custom base URL
Useful for proxying or testing:
client:=paymongo.NewClient("sk_test_xxx","pk_test_xxx",paymongo.WithBaseURL("https://your-proxy.com/paymongo"),)Contributing
Contributions are welcome! Please open an issue or pull request on Codeberg.
License
MIT