Skip to content

Commit

Permalink
feat: add zibal payment gateway
Browse files Browse the repository at this point in the history
  • Loading branch information
ErfanTech committed Mar 18, 2024
1 parent b444947 commit 3e6f5f3
Show file tree
Hide file tree
Showing 4 changed files with 158 additions and 1 deletion.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ go get -u github.com/GoFarsi/paygap

## Usage

example for zarinpal provider ([Other examples](_examples))
example for zarinpal provider ([Other examples](https://github.com/GoFarsi/paygap/tree/main/_example))

```go
package main
Expand Down Expand Up @@ -60,3 +60,4 @@ func main() {
- [ ] parsian
- [ ] pasargad
- [x] sadad
- [x] [zibal](https://zibal.ir)
29 changes: 29 additions & 0 deletions _example/zibal/zibal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package main

import (
"context"
"github.com/GoFarsi/paygap/client"
"github.com/GoFarsi/paygap/providers/zibal"
"log"
)

func main() {
c := client.New()

z, err := zibal.New(c, "zibal")
if err != nil {
log.Fatal(err)
}

resp, err := z.RequestPayment(context.Background(), 5000, "https://example.com", "description")
if err != nil {
log.Fatal(err)
}

trackID := resp.TrackID

_, err = z.VerifyPayment(context.Background(), trackID)
if err != nil {
log.Fatal(err)
}
}
42 changes: 42 additions & 0 deletions providers/zibal/models.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package zibal

import "github.com/GoFarsi/paygap/client"

type Zibal struct {
client client.Transporter
merchant string `validate:"required"`

baseUrl string
requestEndpoint string
verifyEndpoint string
}

type paymentRequest struct {
Merchant string `json:"merchant" validate:"required"`
Amount uint `json:"amount" validate:"required,min=1000"`
CallbackURL string `json:"callbackUrl" validate:"required,url"`
Description string `json:"description"`
}

type PaymentResponse struct {
Result int `json:"result"`
TrackID int `json:"trackId"`
Message string `json:"message"`
}

type VerificationRequest struct {
Merchant string `json:"merchant" validate:"required"`
TrackID int `json:"trackId" validate:"required"`
}

type VerificationResponse struct {
PaidAt string `json:"paidAt"`
Amount int `json:"amount"`
Result int `json:"result"`
Status int `json:"status"`
RefNumber int `json:"refNumber"`
Description string `json:"description"`
CardNumber string `json:"cardNumber"`
OrderID string `json:"orderId"`
Message string `json:"message"`
}
85 changes: 85 additions & 0 deletions providers/zibal/zibal.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package zibal

import (
"context"
"github.com/GoFarsi/paygap/client"
"github.com/GoFarsi/paygap/status"
"net/http"

"google.golang.org/grpc/codes"
)

const zibalBaseURL = "https://gateway.zibal.ir"
const (
zibalRequestEndpoint = "/v1/request"
zibalVerifyEndpoint = "/v1/verify"
)

// New creates a zibal provider object for user factory request methods
func New(client client.Transporter, merchant string) (*Zibal, error) {
if client == nil {
return nil, status.ERR_CLIENT_IS_NIL
}

zibal := &Zibal{
client: client,
merchant: merchant,
baseUrl: zibalBaseURL,
requestEndpoint: zibalRequestEndpoint,
verifyEndpoint: zibalVerifyEndpoint,
}
if err := client.GetValidator().Struct(zibal); err != nil {
return nil, status.New(0, http.StatusBadRequest, codes.InvalidArgument, err.Error())
}

return zibal, nil
}

// RequestPayment creates a payment request and returns a status code and authority.
func (z *Zibal) RequestPayment(ctx context.Context, amount uint, callBackUrl, description string) (*PaymentResponse, error) {
req := &paymentRequest{
Merchant: z.merchant,
Amount: amount,
CallbackURL: callBackUrl,
Description: description,
}
if err := z.client.GetValidator().Struct(req); err != nil {
return nil, status.New(0, http.StatusBadRequest, codes.InvalidArgument, err.Error())
}

response := &PaymentResponse{}
resp, err := z.client.Post(ctx, &client.APIConfig{Host: z.baseUrl, Path: z.requestEndpoint, Headers: map[string]string{"Content-Type": "application/json"}}, req)
if err != nil {
return nil, status.New(0, http.StatusInternalServerError, codes.Internal, err.Error())
}

if err := resp.GetJSON(response); err != nil {
return nil, status.New(0, http.StatusInternalServerError, codes.Internal, err.Error())
}

return response, nil
}

// VerifyPayment verifies a payment and returns the payment details.
func (z *Zibal) VerifyPayment(ctx context.Context, trackID int) (*VerificationResponse, error) {
req := &VerificationRequest{
Merchant: z.merchant,
TrackID: trackID,
}

if err := z.client.GetValidator().Struct(req); err != nil {
return nil, status.New(0, http.StatusBadRequest, codes.InvalidArgument, err.Error())
}

response := &VerificationResponse{}
resp, err := z.client.Post(ctx, &client.APIConfig{Host: z.baseUrl, Path: z.verifyEndpoint, Headers: map[string]string{"Content-Type": "application/json"}}, req)
if err != nil {
return nil, status.New(0, http.StatusInternalServerError, codes.Internal, err.Error())
}

if err := resp.GetJSON(response); err != nil {
return nil, status.New(0, http.StatusInternalServerError, codes.Internal, err.Error())
}

return response, nil
}

0 comments on commit 3e6f5f3

Please sign in to comment.