Skip to content

Commit

Permalink
Merge pull request #7 from mimani68/feat-payping
Browse files Browse the repository at this point in the history
Payment service provider had added to capabilities of PAYGAP package
  • Loading branch information
Ja7ad committed Feb 2, 2023
2 parents fef4583 + 575c2c9 commit 50614d4
Show file tree
Hide file tree
Showing 10 changed files with 4,991 additions and 1 deletion.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@

# Dependency directories (remove the comment below to include it)
# vendor/
.idea
.idea
.vscode
41 changes: 41 additions & 0 deletions _example/payping/payping.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package main

import (
"context"
"fmt"
"log"

"github.com/GoFarsi/paygap/client"
"github.com/GoFarsi/paygap/providers/payping"
)

func main() {
p, err := payping.New(client.New(), "YOUR_API_KEY")
if err != nil {
log.Fatal(err)
}

request := &payping.PaymentRequest{
Amount: 11000,
PayerIdentity: "124500",
PayerName: "Ali Hesami",
ClientRefId: "example-arbitary-code",
ReturnUrl: "http://example.com/callback",
Description: "desc test",
}
resp, err := p.RequestPayment(context.Background(), request)

if err != nil {
log.Fatal(err)
}

fmt.Println(resp)

verify := &payping.VerifyRequest{
Amount: request.Amount,
RefId: resp.Code,
}
verifyResp, err := p.VerifyPayment(context.Background(), verify)

fmt.Println(verifyResp)
}
52 changes: 52 additions & 0 deletions providers/payping/helper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package payping

import (
"context"
"errors"
"fmt"
"net/http"
"reflect"

"github.com/GoFarsi/paygap/client"
"github.com/GoFarsi/paygap/status"
"google.golang.org/grpc/codes"
)

func request[RQ any, RS any](ctx context.Context, payping *Payping, req RQ, baseUrl string, endpoint string, queryParams map[string]string) (response RS, err error) {
r, ok := reflect.New(reflect.TypeOf(response).Elem()).Interface().(RS)
if !ok {
return response, errors.New("response type is invalid")
}

if payping.apiToken == "" || len(payping.apiToken) < 10 {
return response, errors.New("jwt token is invalid")
}

headers := make(map[string]string)
headers["Authorization"] = fmt.Sprintf("Bearer %s", payping.apiToken)
headers["Content-Type"] = "application/json"

// TODO: can review if SANDBOX was available
// if i.sandbox {
// headers["X-SANDBOX"] = "1"
// }

errResp := &ErrorResponse{}
resp, err := payping.client.Post(ctx, &client.APIConfig{Host: baseUrl, Path: endpoint, Headers: headers, Query: queryParams}, req)
if err != nil {
return response, status.New(0, http.StatusInternalServerError, codes.Internal, err.Error())
}

if resp.GetHttpResponse().StatusCode != http.StatusOK|http.StatusCreated {
if err := resp.GetJSON(errResp); err != nil {
return response, status.New(0, http.StatusInternalServerError, codes.Internal, err.Error())
}
return response, status.New(errResp.ErrorCode, http.StatusFailedDependency, codes.OK, errResp.ErrorMessage)
}

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

return r, nil
}
79 changes: 79 additions & 0 deletions providers/payping/models.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package payping

type PaymentRequest struct {
Amount int32 `json:"amount" validate:"required,min=100,max=50000000"`
PayerIdentity string `json:"payerIdentity"`
PayerName string `json:"payerName" validate:"required"`
Description string `json:"description"`
ReturnUrl string `json:"returnUrl" validate:"required,url"`
ClientRefId string `json:"clientRefId"`
}

type PaymentResponse struct {
Code string `json:"code"`
}

type VerifyRequest struct {
RefId string `json:"refId" validate:"required"`
Amount int32 `json:"Amount" validate:"required,min=100,max=50000000"`
}

type VerifyResponse struct {
Amount int32 `json:"amount"`
CardNumber string `json:"cardNumber"`
CardHashPan string `json:"cardHashPan"`
}

type SharePaymentRequest struct {
Pairs []pairs `json:"pairs" validate:"required"`
PayerName string `json:"payerName" validate:"required"`
ReturnUrl string `json:"returnUrl" validate:"required,url"`
ClientRefId string `json:"clientRefId"`
}

type pairs struct {
Amount int32 `json:"amount" validate:"required"`
Name string `json:"name"`
UserIdentity string `json:"userIdentity" validate:"required"`
Description string `json:"description"`
}

type BlockedPaymentRequest struct {
Pairs []pairs `json:"pairs" validate:"required"`
PayerName string `json:"payerName" validate:"required"`
ReturnUrl string `json:"returnUrl" validate:"required,url"`
ClientRefId string `json:"clientRefId"`
}

type ReleasingBlockedPaymentRequest struct {
Code string `json:"code"`
ClientId string `json:"clientId"`
}

type PaymentWithTracerIdRequest struct {
Amount int32 `json:"authority" validate:"required,min=100,max=50000000"`
PayerIdentity string `json:"payerIdentity"`
PayerName string `json:"payerName"`
Description string `json:"description"`
ReturnUrl string `json:"returnUrl" validate:"required,url"`
ClientRefId string `json:"clientRefId"`
}

type PaymentWithTracerIdResponse struct {
Itd int32 `json:"itd"`
Code string `json:"code"`
}

type PaymentSuspedingRequest struct {
Amount int32 `json:"authority" validate:"required,min=100,max=50000000"`
PayerIdentity string `json:"payerIdentity"`
PayerName string `json:"payerName"`
Description string `json:"description"`
ReturnUrl string `json:"returnUrl" validate:"required,url"`
ClientRefId string `json:"clientRefId"`
}

type ErrorResponse struct {
ErrorCode any `json:"error_code"`
ErrorMessage string `json:"error_message"`
}
68 changes: 68 additions & 0 deletions providers/payping/payment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package payping

import (
"context"
"net/http"

"github.com/GoFarsi/paygap/status"
"google.golang.org/grpc/codes"
)

// refrence: https://docs.payping.ir/#operation/CreateSinglePayment
func (p *Payping) RequestPayment(ctx context.Context, req *PaymentRequest) (*PaymentResponse, error) {
if err := p.client.GetValidator().Struct(req); err != nil {
return nil, status.New(0, http.StatusBadRequest, codes.InvalidArgument, err.Error())
}

return request[*PaymentRequest, *PaymentResponse](ctx, p, req, p.baseUrl, p.paymentEndpoint, nil)
}

// refrence: https://docs.payping.ir/#operation/VerifyPayment
func (p *Payping) VerifyPayment(ctx context.Context, req *VerifyRequest) (*VerifyResponse, error) {
if err := p.client.GetValidator().Struct(req); err != nil {
return nil, status.New(0, http.StatusBadRequest, codes.InvalidArgument, err.Error())
}
return request[*VerifyRequest, *VerifyResponse](ctx, p, req, p.baseUrl, p.paymentEndpoint, nil)
}

// refrence: https://docs.payping.ir/#operation/CreateMultiPayment
func (p *Payping) RequestSharePayment(ctx context.Context, req *SharePaymentRequest) (*PaymentResponse, error) {
if err := p.client.GetValidator().Struct(req); err != nil {
return nil, status.New(0, http.StatusBadRequest, codes.InvalidArgument, err.Error())
}
return request[*SharePaymentRequest, *PaymentResponse](ctx, p, req, p.baseUrl, p.paymentEndpoint, nil)
}

// refrence: https://docs.payping.ir/#operation/CreateBlockPayment
func (p *Payping) RequestBlockingPayment(ctx context.Context, req *BlockedPaymentRequest) (*PaymentResponse, error) {
if err := p.client.GetValidator().Struct(req); err != nil {
return nil, status.New(0, http.StatusBadRequest, codes.InvalidArgument, err.Error())
}
return request[*BlockedPaymentRequest, *PaymentResponse](ctx, p, req, p.baseUrl, p.paymentEndpoint, nil)
}

// refrence: https://docs.payping.ir/#operation/UnBlockPayment
func (p *Payping) ReleasingBlockedPayment(ctx context.Context, req *ReleasingBlockedPaymentRequest) error {
if err := p.client.GetValidator().Struct(req); err != nil {
return status.New(0, http.StatusBadRequest, codes.InvalidArgument, err.Error())
}
_, err := request[*ReleasingBlockedPaymentRequest, error](ctx, p, req, p.baseUrl, p.paymentEndpoint, nil)
return err
}

// refrence: https://docs.payping.ir/#operation/CreateIdPosPayment
func (p *Payping) PaymentWithTracingId(ctx context.Context, req *PaymentWithTracerIdRequest) (*PaymentWithTracerIdResponse, error) {
if err := p.client.GetValidator().Struct(req); err != nil {
return nil, status.New(0, http.StatusBadRequest, codes.InvalidArgument, err.Error())
}
return request[*PaymentWithTracerIdRequest, *PaymentWithTracerIdResponse](ctx, p, req, p.baseUrl, p.paymentEndpoint, nil)
}

// refrence: https://docs.payping.ir/#operation/CancelPayment
func (p *Payping) PaymentSuspending(ctx context.Context, req *PaymentSuspedingRequest) error {
if err := p.client.GetValidator().Struct(req); err != nil {
return status.New(0, http.StatusBadRequest, codes.InvalidArgument, err.Error())
}
_, err := request[*PaymentSuspedingRequest, error](ctx, p, req, p.baseUrl, p.paymentEndpoint, nil)
return err
}
55 changes: 55 additions & 0 deletions providers/payping/payping-factory.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package payping

import (
"errors"
"log"
"net/http"

"github.com/GoFarsi/paygap/client"
"github.com/GoFarsi/paygap/status"
"google.golang.org/grpc/codes"
)

const (
PAYPING_HOST = "https://api.payping.ir"
)

const (
PAYPING_REQUEST_API_ENDPOINT = "/v2/pay"
PAYPING_VERIFY_API_ENDPOINT = "/v2/pay/verify"
PAYPING_MULTI_PAYMENT_API_ENDPOINT = "/v2/pay/multi"
PAYPING_BLOCK_MONEY_PAYMENT_API_ENDPOINT = "/v2/pay/BlockMoney"
PAYPING_UNBLOCK_MONEY_PAYMENT_API_ENDPOINT = "/v2/pay/UnBlockMoney"
PAYPING_POS_PAYMENT_API_ENDPOINT = "/v1/pos"
)

// New create payping provider object
func New(client client.Transporter, apiToken string) (*Payping, error) {
if client == nil {
return nil, status.ERR_CLIENT_IS_NIL
}

payping := &Payping{
client: client,
apiToken: apiToken,

baseUrl: PAYPING_HOST,
paymentEndpoint: PAYPING_REQUEST_API_ENDPOINT,
verifyEndpoint: PAYPING_VERIFY_API_ENDPOINT,
multiplePaymentEndpoint: PAYPING_MULTI_PAYMENT_API_ENDPOINT,
blockMoneyPaymentEndpoint: PAYPING_BLOCK_MONEY_PAYMENT_API_ENDPOINT,
unBlockMoneyPaymentEndpoint: PAYPING_UNBLOCK_MONEY_PAYMENT_API_ENDPOINT,
posEndpoint: PAYPING_POS_PAYMENT_API_ENDPOINT,
}

if payping.apiToken == "" || len(payping.apiToken) < 10 {
log.Fatal("jwt token is invalid")
return nil, errors.New("jwt token is invalid")
}

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

return payping, nil
}
19 changes: 19 additions & 0 deletions providers/payping/payping.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package payping

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

type Payping struct {
client client.Transporter

baseUrl string
paymentEndpoint string
verifyEndpoint string
multiplePaymentEndpoint string
blockMoneyPaymentEndpoint string
unBlockMoneyPaymentEndpoint string
posEndpoint string

apiToken string
}
Loading

0 comments on commit 50614d4

Please sign in to comment.