-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #40 from ErfanTech/main
feat: add zibal payment gateway
- Loading branch information
Showing
4 changed files
with
158 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |