diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index d078eed..a3f1f0a 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -1,4 +1,4 @@ -name: Testing +name: Master Checks on: push: branches: diff --git a/.github/workflows/pull_request.yaml b/.github/workflows/pull_request.yaml new file mode 100644 index 0000000..55c6f47 --- /dev/null +++ b/.github/workflows/pull_request.yaml @@ -0,0 +1,26 @@ +name: Running Checks on Pull Request +on: + pull_request: + branches: + - master + +jobs: + test: + name: Test + runs-on: ubuntu-latest + steps: + - name: Set up Go 1.16 + uses: actions/setup-go@v1 + with: + go-version: 1.16 + id: go + + - name: Check out code into the Go module directory + uses: actions/checkout@v1 + + - name: Get dependencies + run: | + go get -v -t -d ./... + + - name: Run Unit Test + run: make test diff --git a/datastore/inmemory/config.go b/datastore/inmemory/config.go index f4234cc..42d1765 100644 --- a/datastore/inmemory/config.go +++ b/datastore/inmemory/config.go @@ -95,6 +95,7 @@ func (r PaymentConfigRepository) FindByPaymentType(ctx context.Context, paymentT case payment.SourceGopay, payment.SourceOvo, payment.SourceLinkAja, + payment.SourceShopeePay, payment.SourceDana: for _, ewallet := range r.config.EWallets { if ewallet.PaymentType == paymentType { diff --git a/example/server/payment-methods.yaml b/example/server/payment-methods.yaml index e861d09..64a2e76 100644 --- a/example/server/payment-methods.yaml +++ b/example/server/payment-methods.yaml @@ -144,7 +144,18 @@ ewallets: currency: "IDR" waiting_time: duration: 15 - unit: minute + unit: minute + - gateway: midtrans + payment_type: "shopeepay" + display_name: "Shopee Pay" + admin_fee: + IDR: + val_percentage: 0 + val_currency: 0 + currency: "IDR" + waiting_time: + duration: 15 + unit: minute cstores: - gateway: midtrans payment_type: alfamart diff --git a/gateway/midtrans/akulaku.go b/gateway/midtrans/akulaku.go deleted file mode 100644 index b49c487..0000000 --- a/gateway/midtrans/akulaku.go +++ /dev/null @@ -1,31 +0,0 @@ -package midtrans - -import ( - gomidtrans "github.com/veritrans/go-midtrans" -) - -// NewAkulaku create snaprequest for akulaku payment source -func NewAkulaku(srb *SnapRequestBuilder) (*Akulaku, error) { - return &Akulaku{ - srb: srb, - }, nil -} - -// Akulaku used for creating snap request for akulaku -type Akulaku struct { - srb *SnapRequestBuilder -} - -// Build ... -func (b *Akulaku) Build() (*gomidtrans.SnapReq, error) { - req, err := b.srb.Build() - if err != nil { - return nil, err - } - - req.EnabledPayments = []gomidtrans.PaymentType{ - gomidtrans.SourceAkulaku, - } - - return req, nil -} diff --git a/gateway/midtrans/akulaku_test.go b/gateway/midtrans/akulaku_test.go deleted file mode 100644 index 89e87a8..0000000 --- a/gateway/midtrans/akulaku_test.go +++ /dev/null @@ -1,25 +0,0 @@ -package midtrans_test - -import ( - "testing" - - "github.com/stretchr/testify/assert" - - . "github.com/imrenagi/go-payment/gateway/midtrans" - gomidtrans "github.com/veritrans/go-midtrans" -) - -func TestAkulaku(t *testing.T) { - - builder := NewSnapRequestBuilder(dummyInv()) - akulaku, _ := NewAkulaku(builder) - - req, err := akulaku.Build() - if err != nil { - t.Logf("expect no error, got %v", err) - t.Fail() - } - - assert.Len(t, req.EnabledPayments, 1) - assert.Contains(t, req.EnabledPayments, gomidtrans.SourceAkulaku) -} diff --git a/gateway/midtrans/alfamart.go b/gateway/midtrans/alfamart.go deleted file mode 100644 index c93b151..0000000 --- a/gateway/midtrans/alfamart.go +++ /dev/null @@ -1,31 +0,0 @@ -package midtrans - -import ( - gomidtrans "github.com/veritrans/go-midtrans" -) - -// NewAlfamart create snaprequest for alfamart payment source -func NewAlfamart(srb *SnapRequestBuilder) (*Alfamart, error) { - return &Alfamart{ - srb: srb, - }, nil -} - -// Alfamart used for creating snap request for alfamart -type Alfamart struct { - srb *SnapRequestBuilder -} - -// Build ... -func (b *Alfamart) Build() (*gomidtrans.SnapReq, error) { - req, err := b.srb.Build() - if err != nil { - return nil, err - } - - req.EnabledPayments = []gomidtrans.PaymentType{ - gomidtrans.SourceAlfamart, - } - - return req, nil -} diff --git a/gateway/midtrans/alfamart_test.go b/gateway/midtrans/alfamart_test.go deleted file mode 100644 index 1dacbf3..0000000 --- a/gateway/midtrans/alfamart_test.go +++ /dev/null @@ -1,25 +0,0 @@ -package midtrans_test - -import ( - "testing" - - "github.com/stretchr/testify/assert" - - . "github.com/imrenagi/go-payment/gateway/midtrans" - gomidtrans "github.com/veritrans/go-midtrans" -) - -func TestAlfamart(t *testing.T) { - - builder := NewSnapRequestBuilder(dummyInv()) - alfamart, _ := NewAlfamart(builder) - - req, err := alfamart.Build() - if err != nil { - t.Logf("expect no error, got %v", err) - t.Fail() - } - - assert.Len(t, req.EnabledPayments, 1) - assert.Contains(t, req.EnabledPayments, gomidtrans.SourceAlfamart) -} diff --git a/gateway/midtrans/bca.go b/gateway/midtrans/bca.go deleted file mode 100644 index 0b0e168..0000000 --- a/gateway/midtrans/bca.go +++ /dev/null @@ -1,31 +0,0 @@ -package midtrans - -import ( - gomidtrans "github.com/veritrans/go-midtrans" -) - -// NewBCAVA create snaprequest for bca_va payment source -func NewBCAVA(srb *SnapRequestBuilder) (*BCAVA, error) { - return &BCAVA{ - srb: srb, - }, nil -} - -// BCAVA used for creating snap request for bca_va -type BCAVA struct { - srb *SnapRequestBuilder -} - -// Build ... -func (b *BCAVA) Build() (*gomidtrans.SnapReq, error) { - req, err := b.srb.Build() - if err != nil { - return nil, err - } - - req.EnabledPayments = []gomidtrans.PaymentType{ - gomidtrans.SourceBCAVA, - } - - return req, nil -} diff --git a/gateway/midtrans/bca_test.go b/gateway/midtrans/bca_test.go deleted file mode 100644 index 46421a8..0000000 --- a/gateway/midtrans/bca_test.go +++ /dev/null @@ -1,25 +0,0 @@ -package midtrans_test - -import ( - "testing" - - "github.com/stretchr/testify/assert" - - . "github.com/imrenagi/go-payment/gateway/midtrans" - gomidtrans "github.com/veritrans/go-midtrans" -) - -func TestBCAVA(t *testing.T) { - - builder := NewSnapRequestBuilder(dummyInv()) - bca, _ := NewBCAVA(builder) - - req, err := bca.Build() - if err != nil { - t.Logf("expect no error, got %v", err) - t.Fail() - } - - assert.Len(t, req.EnabledPayments, 1) - assert.Contains(t, req.EnabledPayments, gomidtrans.SourceBCAVA) -} diff --git a/gateway/midtrans/bni.go b/gateway/midtrans/bni.go deleted file mode 100644 index 69e6287..0000000 --- a/gateway/midtrans/bni.go +++ /dev/null @@ -1,31 +0,0 @@ -package midtrans - -import ( - gomidtrans "github.com/veritrans/go-midtrans" -) - -// NewBNIVA create snaprequest for bni_va payment source -func NewBNIVA(srb *SnapRequestBuilder) (*BNIVA, error) { - return &BNIVA{ - srb: srb, - }, nil -} - -// BNIVA used for creating snap request for bni_va -type BNIVA struct { - srb *SnapRequestBuilder -} - -// Build ... -func (b *BNIVA) Build() (*gomidtrans.SnapReq, error) { - req, err := b.srb.Build() - if err != nil { - return nil, err - } - - req.EnabledPayments = []gomidtrans.PaymentType{ - gomidtrans.SourceBNIVA, - } - - return req, nil -} diff --git a/gateway/midtrans/bni_test.go b/gateway/midtrans/bni_test.go deleted file mode 100644 index 5183ec6..0000000 --- a/gateway/midtrans/bni_test.go +++ /dev/null @@ -1,25 +0,0 @@ -package midtrans_test - -import ( - "testing" - - "github.com/stretchr/testify/assert" - - . "github.com/imrenagi/go-payment/gateway/midtrans" - gomidtrans "github.com/veritrans/go-midtrans" -) - -func TestBNIVA(t *testing.T) { - - builder := NewSnapRequestBuilder(dummyInv()) - bni, _ := NewBNIVA(builder) - - req, err := bni.Build() - if err != nil { - t.Logf("expect no error, got %v", err) - t.Fail() - } - - assert.Len(t, req.EnabledPayments, 1) - assert.Contains(t, req.EnabledPayments, gomidtrans.SourceBNIVA) -} diff --git a/gateway/midtrans/builder.go b/gateway/midtrans/builder.go deleted file mode 100644 index 89dd952..0000000 --- a/gateway/midtrans/builder.go +++ /dev/null @@ -1,124 +0,0 @@ -package midtrans - -import ( - "fmt" - "math" - "time" - - "github.com/imrenagi/go-payment/invoice" - - gomidtrans "github.com/veritrans/go-midtrans" -) - -type requestBuilder interface { - Build() (*gomidtrans.SnapReq, error) -} - -func NewSnapRequestBuilder(inv *invoice.Invoice) *SnapRequestBuilder { - srb := &SnapRequestBuilder{ - snapRequest: &gomidtrans.SnapReq{ - Items: &[]gomidtrans.ItemDetail{}, - }, - } - - return srb. - SetTransactionDetails(inv). - SetCustomerDetail(inv). - SetExpiration(inv). - SetItemDetails(inv) -} - -type SnapRequestBuilder struct { - snapRequest *gomidtrans.SnapReq -} - -func (srb *SnapRequestBuilder) SetItemDetails(inv *invoice.Invoice) *SnapRequestBuilder { - var out []gomidtrans.ItemDetail - - for _, item := range inv.LineItems { - - name := item.Name - if len(item.Name) > 50 { - runes := []rune(name) - name = fmt.Sprintf("%s", string(runes[0:50])) - } - - out = append(out, gomidtrans.ItemDetail{ - ID: item.Category, - Name: name, - Price: int64(item.UnitPrice), - Qty: int32(item.Qty), - Category: item.Category, - MerchantName: item.MerchantName, - }) - } - - if inv.ServiceFee > 0 { - out = append(out, gomidtrans.ItemDetail{ - ID: "adminfee", - Name: "Biaya Admin", - Price: int64(inv.ServiceFee), - Qty: 1, - Category: "FEE", - }) - } - if inv.InstallmentFee > 0 { - out = append(out, gomidtrans.ItemDetail{ - ID: "installmentfee", - Name: "Installment Fee", - Price: int64(inv.InstallmentFee), - Qty: 1, - Category: "FEE", - }) - } - if inv.Discount > 0 { - out = append(out, gomidtrans.ItemDetail{ - ID: "discount", - Name: "Discount", - Price: int64(-1 * inv.Discount), - Qty: 1, - Category: "DISCOUNT", - }) - } - - srb.snapRequest.Items = &out - - return srb -} - -func (srb *SnapRequestBuilder) SetCustomerDetail(inv *invoice.Invoice) *SnapRequestBuilder { - srb.snapRequest.CustomerDetail = &gomidtrans.CustDetail{ - FName: inv.BillingAddress.FullName, - Email: inv.BillingAddress.Email, - Phone: inv.BillingAddress.PhoneNumber, - BillAddr: &gomidtrans.CustAddress{ - FName: inv.BillingAddress.FullName, - Phone: inv.BillingAddress.PhoneNumber, - }, - } - return srb -} - -func (srb *SnapRequestBuilder) SetExpiration(inv *invoice.Invoice) *SnapRequestBuilder { - loc, _ := time.LoadLocation("Asia/Jakarta") - invDate := inv.InvoiceDate.In(loc) - duration := inv.DueDate.Sub(inv.InvoiceDate) - srb.snapRequest.Expiry = &gomidtrans.ExpiryDetail{ - StartTime: invDate.Format("2006-01-02 15:04:05 -0700"), - Unit: "hour", - Duration: int64(math.Round(duration.Hours())), - } - return srb -} - -func (srb *SnapRequestBuilder) SetTransactionDetails(inv *invoice.Invoice) *SnapRequestBuilder { - srb.snapRequest.TransactionDetails = gomidtrans.TransactionDetails{ - OrderID: inv.Number, - GrossAmt: int64(inv.GetTotal()), - } - return srb -} - -func (srb *SnapRequestBuilder) Build() (*gomidtrans.SnapReq, error) { - return srb.snapRequest, nil -} diff --git a/gateway/midtrans/builder_test.go b/gateway/midtrans/builder_test.go deleted file mode 100644 index 698a9e2..0000000 --- a/gateway/midtrans/builder_test.go +++ /dev/null @@ -1,77 +0,0 @@ -package midtrans_test - -import ( - "testing" - - "github.com/stretchr/testify/assert" - - . "github.com/imrenagi/go-payment/gateway/midtrans" -) - -func TestNewSnapRequestBuilder(t *testing.T) { - - builder := NewSnapRequestBuilder(dummyInv()) - req, err := builder.Build() - if err != nil { - t.Logf("expect no error, got %v", err) - t.Fail() - } - - assert.NotEmpty(t, req.TransactionDetails.OrderID) - assert.Equal(t, int64(5000), req.TransactionDetails.GrossAmt) - assert.Equal(t, "2020-08-01 08:00:00 +0700", req.Expiry.StartTime) - assert.Equal(t, "hour", req.Expiry.Unit) - assert.Equal(t, int64(24), req.Expiry.Duration) - assert.Equal(t, "Foo", req.CustomerDetail.FName) - assert.Empty(t, req.CustomerDetail.LName) - assert.Equal(t, "0812312412", req.CustomerDetail.Phone) - assert.Equal(t, "Foo", req.CustomerDetail.BillAddr.FName) - assert.Equal(t, "0812312412", req.CustomerDetail.BillAddr.Phone) - assert.NotNil(t, 1, len(*req.Items)) -} - -func TestNewSnapRequestBuilder_LongItemName(t *testing.T) { - - i := dummyInv() - i.LineItems[0].Name = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. " - - builder := NewSnapRequestBuilder(i) - req, err := builder.Build() - if err != nil { - t.Logf("expect no error, got %v", err) - t.Fail() - } - - items := *req.Items - assert.Len(t, items[0].Name, 50) -} - -func TestNewSnapRequestBuilder_WithDiscount(t *testing.T) { - - inv := dummyInv() - inv.Discount = 500 - - builder := NewSnapRequestBuilder(inv) - req, err := builder.Build() - if err != nil { - t.Logf("expect no error, got %v", err) - t.Fail() - } - - assert.NotEmpty(t, req.TransactionDetails.OrderID) - assert.Equal(t, int64(4500), req.TransactionDetails.GrossAmt) - assert.Equal(t, "2020-08-01 08:00:00 +0700", req.Expiry.StartTime) - assert.Equal(t, "hour", req.Expiry.Unit) - assert.Equal(t, int64(24), req.Expiry.Duration) - assert.Equal(t, "Foo", req.CustomerDetail.FName) - assert.Empty(t, req.CustomerDetail.LName) - assert.Equal(t, "0812312412", req.CustomerDetail.Phone) - assert.Equal(t, "Foo", req.CustomerDetail.BillAddr.FName) - assert.Equal(t, "0812312412", req.CustomerDetail.BillAddr.Phone) - assert.Equal(t, 2, len(*req.Items)) - - items := *req.Items - - assert.Equal(t, int64(5000), items[0].Price) - assert.Equal(t, int64(-500), items[1].Price) -} diff --git a/gateway/midtrans/credit_card.go b/gateway/midtrans/credit_card.go deleted file mode 100644 index 8263573..0000000 --- a/gateway/midtrans/credit_card.go +++ /dev/null @@ -1,61 +0,0 @@ -package midtrans - -import ( - "github.com/imrenagi/go-payment" - "github.com/imrenagi/go-payment/invoice" - gomidtrans "github.com/veritrans/go-midtrans" -) - -// NewCreditCard create snaprequest for bca_va payment source -func NewCreditCard(srb *SnapRequestBuilder, creditCardDetail *invoice.CreditCardDetail) (*CreditCard, error) { - return &CreditCard{ - srb: srb, - creditCardDetail: creditCardDetail, - }, nil -} - -// CreditCard used for creating snap request for bca_va -type CreditCard struct { - srb *SnapRequestBuilder - creditCardDetail *invoice.CreditCardDetail -} - -// Build ... -func (b *CreditCard) Build() (*gomidtrans.SnapReq, error) { - req, err := b.srb.Build() - if err != nil { - return nil, err - } - - req.EnabledPayments = []gomidtrans.PaymentType{ - gomidtrans.SourceCreditCard, - } - - ccDetail := &gomidtrans.CreditCardDetail{ - Secure: true, - Bank: string(gomidtrans.BankBca), - Authentication: "3ds", - } - - if b.creditCardDetail != nil { - var installmentTermsDetail gomidtrans.InstallmentTermsDetail - switch b.creditCardDetail.Installment.Type { - case payment.InstallmentOffline: - if b.creditCardDetail.Installment.Term > 0 { - installmentTermsDetail = gomidtrans.InstallmentTermsDetail{ - Offline: []int8{ - int8(b.creditCardDetail.Installment.Term), - }, - } - - ccDetail.Installment = &gomidtrans.InstallmentDetail{ - Required: true, - Terms: &installmentTermsDetail, - } - } - } - } - req.CreditCard = ccDetail - - return req, nil -} diff --git a/gateway/midtrans/facade.go b/gateway/midtrans/facade.go index 4f361e2..12c2920 100644 --- a/gateway/midtrans/facade.go +++ b/gateway/midtrans/facade.go @@ -2,40 +2,39 @@ package midtrans import ( "github.com/imrenagi/go-payment" + "github.com/imrenagi/go-payment/gateway/midtrans/snap" "github.com/imrenagi/go-payment/invoice" - gomidtrans "github.com/veritrans/go-midtrans" -) -func NewSnapRequestFromInvoice(inv *invoice.Invoice) (*gomidtrans.SnapReq, error) { + "fmt" - var reqBuilder requestBuilder - var err error + midsnap "github.com/midtrans/midtrans-go/snap" +) - snapRequestBuilder := NewSnapRequestBuilder(inv) +// NewSnapFromInvoice create snap charge request +func NewSnapFromInvoice(inv *invoice.Invoice) (*midsnap.Request, error) { switch inv.Payment.PaymentType { case payment.SourceBCAVA: - reqBuilder, err = NewBCAVA(snapRequestBuilder) + return snap.NewBCAVA(inv) case payment.SourcePermataVA: - reqBuilder, err = NewPermataVA(snapRequestBuilder) + return snap.NewPermataVA(inv) case payment.SourceMandiriVA: - reqBuilder, err = NewMandiriBill(snapRequestBuilder) + return snap.NewMandiriVA(inv) case payment.SourceBNIVA: - reqBuilder, err = NewBNIVA(snapRequestBuilder) + return snap.NewBNIVA(inv) case payment.SourceOtherVA: - reqBuilder, err = NewOtherBank(snapRequestBuilder) - case payment.SourceGopay: - reqBuilder, err = NewGopay(snapRequestBuilder) + return snap.NewOtherBankVA(inv) case payment.SourceAlfamart: - reqBuilder, err = NewAlfamart(snapRequestBuilder) + return snap.NewAlfamart(inv) case payment.SourceAkulaku: - reqBuilder, err = NewAkulaku(snapRequestBuilder) + return snap.NewAkulaku(inv) + case payment.SourceGopay: + return snap.NewGopay(inv) case payment.SourceCreditCard: - reqBuilder, err = NewCreditCard(snapRequestBuilder, inv.Payment.CreditCardDetail) - } - if err != nil { - return nil, err + return snap.NewCreditCard(inv) + case payment.SourceShopeePay: + return snap.NewShopeePay(inv) + default: + return nil, fmt.Errorf("payment type not known") } - - return reqBuilder.Build() } diff --git a/gateway/midtrans/gateway.go b/gateway/midtrans/gateway.go index fe2bcba..4ae4879 100644 --- a/gateway/midtrans/gateway.go +++ b/gateway/midtrans/gateway.go @@ -3,29 +3,31 @@ package midtrans import ( "os" + "github.com/midtrans/midtrans-go" + "github.com/midtrans/midtrans-go/snap" + "github.com/imrenagi/go-payment/util/localconfig" - mgo "github.com/veritrans/go-midtrans" ) // NewGateway creates new midtrans payment gateway func NewGateway(creds localconfig.APICredential) *Gateway { - midclient := mgo.NewClient() - midclient.ServerKey = creds.SecretKey - midclient.ClientKey = creds.ClientKey + snapClient := &snap.Client{ + ServerKey: creds.SecretKey, + } switch os.Getenv("ENVIRONMENT") { case "prod": - midclient.APIEnvType = mgo.Production + snapClient.Env = midtrans.Production + snapClient.HttpClient = midtrans.GetHttpClient(midtrans.Production) default: - midclient.APIEnvType = mgo.Sandbox + snapClient.Env = midtrans.Sandbox + snapClient.HttpClient = midtrans.GetHttpClient(midtrans.Sandbox) } gateway := Gateway{ - midClient: midclient, - SnapGateway: &mgo.SnapGateway{ - Client: midclient, - }, + serverKey: creds.SecretKey, + SnapV2Gateway: snapClient, } return &gateway @@ -33,17 +35,16 @@ func NewGateway(creds localconfig.APICredential) *Gateway { // Gateway stores go-midtrans gateway and client type Gateway struct { - midClient mgo.Client - SnapGateway SnapGateway + serverKey string + SnapV2Gateway SnapGateway } // NotificationValidationKey returns midtrans server key used for validating // midtransa transaction status func (g Gateway) NotificationValidationKey() string { - return g.midClient.ServerKey + return g.serverKey } -// SnapGateway interaction interface with midtrans snap server type SnapGateway interface { - GetToken(r *mgo.SnapReq) (mgo.SnapResponse, error) + CreateTransaction(req *snap.Request) (*snap.Response, *midtrans.Error) } diff --git a/gateway/midtrans/gopay.go b/gateway/midtrans/gopay.go deleted file mode 100644 index 59266df..0000000 --- a/gateway/midtrans/gopay.go +++ /dev/null @@ -1,31 +0,0 @@ -package midtrans - -import ( - gomidtrans "github.com/veritrans/go-midtrans" -) - -// NewGopay create snaprequest for gopay payment source -func NewGopay(srb *SnapRequestBuilder) (*Gopay, error) { - return &Gopay{ - srb: srb, - }, nil -} - -// Gopay used for creating snap request for gopay -type Gopay struct { - srb *SnapRequestBuilder -} - -// Build ... -func (b *Gopay) Build() (*gomidtrans.SnapReq, error) { - req, err := b.srb.Build() - if err != nil { - return nil, err - } - - req.EnabledPayments = []gomidtrans.PaymentType{ - gomidtrans.SourceGopay, - } - - return req, nil -} diff --git a/gateway/midtrans/gopay_test.go b/gateway/midtrans/gopay_test.go deleted file mode 100644 index 531b80d..0000000 --- a/gateway/midtrans/gopay_test.go +++ /dev/null @@ -1,25 +0,0 @@ -package midtrans_test - -import ( - "testing" - - "github.com/stretchr/testify/assert" - - . "github.com/imrenagi/go-payment/gateway/midtrans" - gomidtrans "github.com/veritrans/go-midtrans" -) - -func TestGopay(t *testing.T) { - - builder := NewSnapRequestBuilder(dummyInv()) - gopay, _ := NewGopay(builder) - - req, err := gopay.Build() - if err != nil { - t.Logf("expect no error, got %v", err) - t.Fail() - } - - assert.Len(t, req.EnabledPayments, 1) - assert.Contains(t, req.EnabledPayments, gomidtrans.SourceGopay) -} diff --git a/gateway/midtrans/mandiri.go b/gateway/midtrans/mandiri.go deleted file mode 100644 index 6fd43fa..0000000 --- a/gateway/midtrans/mandiri.go +++ /dev/null @@ -1,31 +0,0 @@ -package midtrans - -import ( - gomidtrans "github.com/veritrans/go-midtrans" -) - -// NewMandiriBill create snaprequest for mandiri echannel payment source -func NewMandiriBill(srb *SnapRequestBuilder) (*MandiriBill, error) { - return &MandiriBill{ - srb: srb, - }, nil -} - -// MandiriBill used for creating snap request for mandiri echannel -type MandiriBill struct { - srb *SnapRequestBuilder -} - -// Build ... -func (b *MandiriBill) Build() (*gomidtrans.SnapReq, error) { - req, err := b.srb.Build() - if err != nil { - return nil, err - } - - req.EnabledPayments = []gomidtrans.PaymentType{ - gomidtrans.SourceEchannel, - } - - return req, nil -} diff --git a/gateway/midtrans/mandiri_test.go b/gateway/midtrans/mandiri_test.go deleted file mode 100644 index 721c5f7..0000000 --- a/gateway/midtrans/mandiri_test.go +++ /dev/null @@ -1,25 +0,0 @@ -package midtrans_test - -import ( - "testing" - - "github.com/stretchr/testify/assert" - - . "github.com/imrenagi/go-payment/gateway/midtrans" - gomidtrans "github.com/veritrans/go-midtrans" -) - -func TestMandiriVA(t *testing.T) { - - builder := NewSnapRequestBuilder(dummyInv()) - mandiri, _ := NewMandiriBill(builder) - - req, err := mandiri.Build() - if err != nil { - t.Logf("expect no error, got %v", err) - t.Fail() - } - - assert.Len(t, req.EnabledPayments, 1) - assert.Contains(t, req.EnabledPayments, gomidtrans.SourceEchannel) -} diff --git a/gateway/midtrans/other_bank.go b/gateway/midtrans/other_bank.go deleted file mode 100644 index 4d7c89a..0000000 --- a/gateway/midtrans/other_bank.go +++ /dev/null @@ -1,31 +0,0 @@ -package midtrans - -import ( - gomidtrans "github.com/veritrans/go-midtrans" -) - -// NewOtherBank create snaprequest for other_va payment source -func NewOtherBank(srb *SnapRequestBuilder) (*OtherBank, error) { - return &OtherBank{ - srb: srb, - }, nil -} - -// OtherBank used for creating snap request for other_va -type OtherBank struct { - srb *SnapRequestBuilder -} - -// Build ... -func (b *OtherBank) Build() (*gomidtrans.SnapReq, error) { - req, err := b.srb.Build() - if err != nil { - return nil, err - } - - req.EnabledPayments = []gomidtrans.PaymentType{ - gomidtrans.SourceOtherVA, - } - - return req, nil -} diff --git a/gateway/midtrans/other_bank_test.go b/gateway/midtrans/other_bank_test.go deleted file mode 100644 index c0be686..0000000 --- a/gateway/midtrans/other_bank_test.go +++ /dev/null @@ -1,25 +0,0 @@ -package midtrans_test - -import ( - "testing" - - "github.com/stretchr/testify/assert" - - . "github.com/imrenagi/go-payment/gateway/midtrans" - gomidtrans "github.com/veritrans/go-midtrans" -) - -func TestOtherBankVA(t *testing.T) { - - builder := NewSnapRequestBuilder(dummyInv()) - other, _ := NewOtherBank(builder) - - req, err := other.Build() - if err != nil { - t.Logf("expect no error, got %v", err) - t.Fail() - } - - assert.Len(t, req.EnabledPayments, 1) - assert.Contains(t, req.EnabledPayments, gomidtrans.SourceOtherVA) -} diff --git a/gateway/midtrans/permata.go b/gateway/midtrans/permata.go deleted file mode 100644 index 137cf78..0000000 --- a/gateway/midtrans/permata.go +++ /dev/null @@ -1,31 +0,0 @@ -package midtrans - -import ( - gomidtrans "github.com/veritrans/go-midtrans" -) - -// NewPermataVA create snaprequest for permata_va payment source -func NewPermataVA(srb *SnapRequestBuilder) (*PermataVA, error) { - return &PermataVA{ - srb: srb, - }, nil -} - -// PermataVA used for creating snap request for permata_va -type PermataVA struct { - srb *SnapRequestBuilder -} - -// Build ... -func (b *PermataVA) Build() (*gomidtrans.SnapReq, error) { - req, err := b.srb.Build() - if err != nil { - return nil, err - } - - req.EnabledPayments = []gomidtrans.PaymentType{ - gomidtrans.SourcePermataVA, - } - - return req, nil -} diff --git a/gateway/midtrans/permata_test.go b/gateway/midtrans/permata_test.go deleted file mode 100644 index a27041e..0000000 --- a/gateway/midtrans/permata_test.go +++ /dev/null @@ -1,25 +0,0 @@ -package midtrans_test - -import ( - "testing" - - "github.com/stretchr/testify/assert" - - . "github.com/imrenagi/go-payment/gateway/midtrans" - gomidtrans "github.com/veritrans/go-midtrans" -) - -func TestPermataVA(t *testing.T) { - - builder := NewSnapRequestBuilder(dummyInv()) - permata, _ := NewPermataVA(builder) - - req, err := permata.Build() - if err != nil { - t.Logf("expect no error, got %v", err) - t.Fail() - } - - assert.Len(t, req.EnabledPayments, 1) - assert.Contains(t, req.EnabledPayments, gomidtrans.SourcePermataVA) -} diff --git a/gateway/midtrans/snap/akulaku.go b/gateway/midtrans/snap/akulaku.go new file mode 100644 index 0000000..625ddae --- /dev/null +++ b/gateway/midtrans/snap/akulaku.go @@ -0,0 +1,13 @@ +package snap + +import ( + "github.com/midtrans/midtrans-go/snap" + + "github.com/imrenagi/go-payment/invoice" +) + +func NewAkulaku(inv *invoice.Invoice) (*snap.Request, error) { + return newBuilder(inv). + AddPaymentMethods(snap.PaymentTypeAkulaku). + Build() +} diff --git a/gateway/midtrans/snap/akulaku_test.go b/gateway/midtrans/snap/akulaku_test.go new file mode 100644 index 0000000..545dcc2 --- /dev/null +++ b/gateway/midtrans/snap/akulaku_test.go @@ -0,0 +1,40 @@ +package snap_test + +import ( + "testing" + + midsnap "github.com/midtrans/midtrans-go/snap" + "github.com/stretchr/testify/assert" + + "github.com/imrenagi/go-payment/gateway/midtrans/snap" + "github.com/imrenagi/go-payment/invoice" +) + +func TestNewAkulaku(t *testing.T) { + type args struct { + inv *invoice.Invoice + } + tests := []struct { + name string + args args + want *midsnap.Request + wantErr error + }{ + { + name: "standard bni va request", + args: args{inv: dummyInv}, + want: &midsnap.Request{ + EnabledPayments: []midsnap.SnapPaymentType{ + midsnap.PaymentTypeAkulaku, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := snap.NewAkulaku(tt.args.inv) + assert.Equal(t, tt.wantErr, err) + assert.Contains(t, got.EnabledPayments, midsnap.PaymentTypeAkulaku) + }) + } +} diff --git a/gateway/midtrans/snap/alfamart.go b/gateway/midtrans/snap/alfamart.go new file mode 100644 index 0000000..bb6fbcb --- /dev/null +++ b/gateway/midtrans/snap/alfamart.go @@ -0,0 +1,13 @@ +package snap + +import ( + "github.com/midtrans/midtrans-go/snap" + + "github.com/imrenagi/go-payment/invoice" +) + +func NewAlfamart(inv *invoice.Invoice) (*snap.Request, error) { + return newBuilder(inv). + AddPaymentMethods(snap.PaymentTypeAlfamart). + Build() +} diff --git a/gateway/midtrans/snap/alfamart_test.go b/gateway/midtrans/snap/alfamart_test.go new file mode 100644 index 0000000..38208a7 --- /dev/null +++ b/gateway/midtrans/snap/alfamart_test.go @@ -0,0 +1,41 @@ +package snap_test + +import ( + "testing" + + midsnap "github.com/midtrans/midtrans-go/snap" + "github.com/stretchr/testify/assert" + + "github.com/imrenagi/go-payment/gateway/midtrans/snap" + "github.com/imrenagi/go-payment/invoice" +) + +func TestNewAlfamart(t *testing.T) { + type args struct { + inv *invoice.Invoice + } + tests := []struct { + name string + args args + want *midsnap.Request + wantErr error + }{ + { + name: "standard bni va request", + args: args{inv: dummyInv}, + want: &midsnap.Request{ + EnabledPayments: []midsnap.SnapPaymentType{ + midsnap.PaymentTypeAlfamart, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := snap.NewAlfamart(tt.args.inv) + assert.Equal(t, tt.wantErr, err) + assert.EqualValues(t, tt.want.Cstore, got.Cstore) + assert.Contains(t, got.EnabledPayments, midsnap.PaymentTypeAlfamart) + }) + } +} diff --git a/gateway/midtrans/snap/bca.go b/gateway/midtrans/snap/bca.go new file mode 100644 index 0000000..e282c40 --- /dev/null +++ b/gateway/midtrans/snap/bca.go @@ -0,0 +1,13 @@ +package snap + +import ( + "github.com/midtrans/midtrans-go/snap" + + "github.com/imrenagi/go-payment/invoice" +) + +func NewBCAVA(inv *invoice.Invoice) (*snap.Request, error) { + return newBuilder(inv). + AddPaymentMethods(snap.PaymentTypeBCAVA). + Build() +} diff --git a/gateway/midtrans/snap/bca_test.go b/gateway/midtrans/snap/bca_test.go new file mode 100644 index 0000000..0ee9606 --- /dev/null +++ b/gateway/midtrans/snap/bca_test.go @@ -0,0 +1,41 @@ +package snap_test + +import ( + "testing" + + midsnap "github.com/midtrans/midtrans-go/snap" + "github.com/stretchr/testify/assert" + + "github.com/imrenagi/go-payment/gateway/midtrans/snap" + "github.com/imrenagi/go-payment/invoice" +) + +func TestNewBCAVA(t *testing.T) { + type args struct { + inv *invoice.Invoice + } + tests := []struct { + name string + args args + want *midsnap.Request + wantErr error + }{ + { + name: "standard bni va request", + args: args{inv: dummyInv}, + want: &midsnap.Request{ + EnabledPayments: []midsnap.SnapPaymentType{ + midsnap.PaymentTypeBCAVA, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := snap.NewBCAVA(tt.args.inv) + assert.Equal(t, tt.wantErr, err) + assert.EqualValues(t, tt.want.BcaVa, got.BcaVa) + assert.Contains(t, got.EnabledPayments, midsnap.PaymentTypeBCAVA) + }) + } +} diff --git a/gateway/midtrans/snap/bni.go b/gateway/midtrans/snap/bni.go new file mode 100644 index 0000000..e98ffd4 --- /dev/null +++ b/gateway/midtrans/snap/bni.go @@ -0,0 +1,13 @@ +package snap + +import ( + "github.com/midtrans/midtrans-go/snap" + + "github.com/imrenagi/go-payment/invoice" +) + +func NewBNIVA(inv *invoice.Invoice) (*snap.Request, error) { + return newBuilder(inv). + AddPaymentMethods(snap.PaymentTypeBNIVA). + Build() +} diff --git a/gateway/midtrans/snap/bni_test.go b/gateway/midtrans/snap/bni_test.go new file mode 100644 index 0000000..5fdb910 --- /dev/null +++ b/gateway/midtrans/snap/bni_test.go @@ -0,0 +1,41 @@ +package snap_test + +import ( + "testing" + + midsnap "github.com/midtrans/midtrans-go/snap" + "github.com/stretchr/testify/assert" + + "github.com/imrenagi/go-payment/gateway/midtrans/snap" + "github.com/imrenagi/go-payment/invoice" +) + +func TestNewBNIVA(t *testing.T) { + type args struct { + inv *invoice.Invoice + } + tests := []struct { + name string + args args + want *midsnap.Request + wantErr error + }{ + { + name: "standard bni va request", + args: args{inv: dummyInv}, + want: &midsnap.Request{ + EnabledPayments: []midsnap.SnapPaymentType{ + midsnap.PaymentTypeBNIVA, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := snap.NewBNIVA(tt.args.inv) + assert.Equal(t, tt.wantErr, err) + assert.EqualValues(t, tt.want.BniVa, got.BniVa) + assert.Contains(t, got.EnabledPayments, midsnap.PaymentTypeBNIVA) + }) + } +} diff --git a/gateway/midtrans/snap/builder.go b/gateway/midtrans/snap/builder.go new file mode 100644 index 0000000..b39b2b4 --- /dev/null +++ b/gateway/midtrans/snap/builder.go @@ -0,0 +1,140 @@ +package snap + +import ( + "fmt" + "math" + "time" + + "github.com/midtrans/midtrans-go" + "github.com/midtrans/midtrans-go/snap" + + "github.com/imrenagi/go-payment/invoice" +) + +func newBuilder(inv *invoice.Invoice) *builder { + srb := &builder{ + req: &snap.Request{ + Items: &[]midtrans.ItemDetails{}, + }, + } + + return srb. + setTransactionDetails(inv). + setCustomerDetail(inv). + setExpiration(inv). + setItemDetails(inv) +} + +type builder struct { + req *snap.Request +} + +func (b *builder) setItemDetails(inv *invoice.Invoice) *builder { + var out []midtrans.ItemDetails + + for _, item := range inv.LineItems { + + name := item.Name + if len(item.Name) > 50 { + runes := []rune(name) + name = fmt.Sprintf("%s", string(runes[0:50])) + } + + out = append(out, midtrans.ItemDetails{ + ID: fmt.Sprintf("%d", item.ID), + Name: name, + Price: int64(item.UnitPrice), + Qty: int32(item.Qty), + Category: item.Category, + MerchantName: item.MerchantName, + }) + } + + if inv.ServiceFee > 0 { + out = append(out, midtrans.ItemDetails{ + ID: "adminfee", + Name: "Biaya Admin", + Price: int64(inv.ServiceFee), + Qty: 1, + Category: "FEE", + }) + } + if inv.InstallmentFee > 0 { + out = append(out, midtrans.ItemDetails{ + ID: "installmentfee", + Name: "Installment Fee", + Price: int64(inv.InstallmentFee), + Qty: 1, + Category: "FEE", + }) + } + if inv.Discount > 0 { + out = append(out, midtrans.ItemDetails{ + ID: "discount", + Name: "Discount", + Price: int64(-1 * inv.Discount), + Qty: 1, + Category: "DISCOUNT", + }) + } + if inv.Tax > 0 { + out = append(out, midtrans.ItemDetails{ + ID: "tax", + Name: "Tax", + Price: int64(inv.Tax), + Qty: 1, + Category: "TAX", + }) + } + + b.req.Items = &out + + return b +} + +func (b *builder) setCustomerDetail(inv *invoice.Invoice) *builder { + b.req.CustomerDetail = &midtrans.CustomerDetails{ + FName: inv.BillingAddress.FullName, + Email: inv.BillingAddress.Email, + Phone: inv.BillingAddress.PhoneNumber, + BillAddr: &midtrans.CustomerAddress{ + FName: inv.BillingAddress.FullName, + Phone: inv.BillingAddress.PhoneNumber, + }, + } + return b +} + +func (b *builder) setExpiration(inv *invoice.Invoice) *builder { + loc, _ := time.LoadLocation("Asia/Jakarta") + invDate := inv.InvoiceDate.In(loc) + duration := inv.DueDate.Sub(inv.InvoiceDate) + b.req.Expiry = &snap.ExpiryDetails{ + StartTime: invDate.Format("2006-01-02 15:04:05 -0700"), + Unit: "hour", + Duration: int64(math.Round(duration.Hours())), + } + return b +} + +func (b *builder) setTransactionDetails(inv *invoice.Invoice) *builder { + b.req.TransactionDetails = midtrans.TransactionDetails{ + OrderID: inv.Number, + GrossAmt: int64(inv.GetTotal()), + } + return b +} + +func (b *builder) AddPaymentMethods(m snap.SnapPaymentType) *builder { + b.req.EnabledPayments = append(b.req.EnabledPayments, m) + return b +} + +func (b *builder) SetCreditCardDetail(d *snap.CreditCardDetails) *builder { + b.req.CreditCard = d + return b +} + +func (b *builder) Build() (*snap.Request, error) { + return b.req, nil +} diff --git a/gateway/midtrans/snap/common_test.go b/gateway/midtrans/snap/common_test.go new file mode 100644 index 0000000..1138b92 --- /dev/null +++ b/gateway/midtrans/snap/common_test.go @@ -0,0 +1,46 @@ +package snap_test + +import ( + "time" + + "github.com/imrenagi/go-payment" + "github.com/imrenagi/go-payment/invoice" +) + +var fakeInvDate = time.Date(2021, 1, 1, 0, 0, 0, 0, time.UTC) +var fakeDueDate = time.Date(2021, 1, 2, 0, 0, 0, 0, time.UTC) + +var dummyInv = &invoice.Invoice{ + Model: payment.Model{}, + Number: "a-random-invoice-number", + InvoiceDate: fakeInvDate, + DueDate: fakeDueDate, + PaidAt: nil, + Currency: "IDR", + SubTotal: 15000, + Discount: 1000, + Tax: 200, + ServiceFee: 500, + InstallmentFee: 1000, + LineItems: []invoice.LineItem{ + { + Model: payment.Model{ + ID: 1, + }, + InvoiceID: 1, + Name: "random-item", + Description: "just description", + Category: "HOME", + Currency: "IDR", + UnitPrice: 15000, + Qty: 1, + }, + }, + Payment: nil, + BillingAddress: &invoice.BillingAddress{ + FullName: "John Doe", + Email: "foo@bar.com", + PhoneNumber: "08111231234", + }, + SubscriptionID: nil, +} diff --git a/gateway/midtrans/snap/credit_card.go b/gateway/midtrans/snap/credit_card.go new file mode 100644 index 0000000..d142f53 --- /dev/null +++ b/gateway/midtrans/snap/credit_card.go @@ -0,0 +1,42 @@ +package snap + +import ( + "github.com/imrenagi/go-payment" + "github.com/imrenagi/go-payment/invoice" + "github.com/midtrans/midtrans-go" + midsnap "github.com/midtrans/midtrans-go/snap" +) + +func NewCreditCard(inv *invoice.Invoice) (*midsnap.Request, error) { + + ccDetail := &midsnap.CreditCardDetails{ + Secure: true, + Bank: string(midtrans.BankBca), + Channel: "migs", + Type: "", + Installment: nil, + } + + detail := inv.Payment.CreditCardDetail + if detail != nil { + switch detail.Installment.Type { + case payment.InstallmentOffline: + if detail.Installment.Term > 0 { + installmentTermsDetail := midsnap.InstallmentTermsDetail{ + Offline: []int8{ + int8(detail.Installment.Term), + }, + } + ccDetail.Installment = &midsnap.InstallmentDetail{ + Required: true, + Terms: &installmentTermsDetail, + } + } + } + } + + return newBuilder(inv). + AddPaymentMethods(midsnap.PaymentTypeCreditCard). + SetCreditCardDetail(ccDetail). + Build() +} diff --git a/gateway/midtrans/credit_card_test.go b/gateway/midtrans/snap/credit_card_test.go similarity index 57% rename from gateway/midtrans/credit_card_test.go rename to gateway/midtrans/snap/credit_card_test.go index 7b7b251..f63f7cf 100644 --- a/gateway/midtrans/credit_card_test.go +++ b/gateway/midtrans/snap/credit_card_test.go @@ -1,47 +1,62 @@ -package midtrans_test +package snap_test import ( + "context" "testing" + "time" "github.com/imrenagi/go-payment" + "github.com/imrenagi/go-payment/gateway/midtrans/snap" "github.com/imrenagi/go-payment/invoice" - + midsnap "github.com/midtrans/midtrans-go/snap" "github.com/stretchr/testify/assert" - - . "github.com/imrenagi/go-payment/gateway/midtrans" - gomidtrans "github.com/veritrans/go-midtrans" ) +func baseCreditCardInvoice() *invoice.Invoice { + date := time.Date(2020, 8, 1, 1, 0, 0, 0, time.UTC) + dueDate := date.Add(24 * time.Hour) + i := invoice.New(date, dueDate) + + i.SubTotal = 5000 + i.UpsertBillingAddress("Foo", "foo@bar.com", "0812312412") + + i.SetItems(context.TODO(), + []invoice.LineItem{ + { + InvoiceID: 1, + Name: "Terjemahan B", + Category: "TRANSLATION", + MerchantName: "Collegos", + Currency: "IDR", + UnitPrice: 5000, + Qty: 1, + }}, + ) + return i +} + func TestCreditCardWithoutInstallment(t *testing.T) { - inv := dummyInv() + inv := baseCreditCardInvoice() inv.ServiceFee = 1000 inv.Payment = &invoice.Payment{ PaymentType: payment.SourceCreditCard, } - builder := NewSnapRequestBuilder(inv) - cc, _ := NewCreditCard(builder, inv.Payment.CreditCardDetail) - - req, err := cc.Build() - if err != nil { - t.Logf("expect no error, got %v", err) - t.Fail() - } + req, err := snap.NewCreditCard(inv) + assert.NoError(t, err) assert.Len(t, req.EnabledPayments, 1) assert.Equal(t, int64(6000), req.TransactionDetails.GrossAmt) assert.Equal(t, 2, len(*req.Items)) - assert.Contains(t, req.EnabledPayments, gomidtrans.SourceCreditCard) + assert.Contains(t, req.EnabledPayments, midsnap.PaymentTypeCreditCard) assert.True(t, req.CreditCard.Secure) assert.Equal(t, "bca", req.CreditCard.Bank) - assert.Equal(t, "3ds", req.CreditCard.Authentication) - } func TestCreditCardWithInstallment(t *testing.T) { - inv := dummyInv() + inv := baseCreditCardInvoice() inv.InstallmentFee = 2000 inv.Payment = &invoice.Payment{ PaymentType: payment.SourceCreditCard, @@ -53,22 +68,14 @@ func TestCreditCardWithInstallment(t *testing.T) { Bank: payment.BankBCA, }, } - builder := NewSnapRequestBuilder(inv) - cc, _ := NewCreditCard(builder, inv.Payment.CreditCardDetail) - - req, err := cc.Build() - if err != nil { - t.Logf("expect no error, got %v", err) - t.Fail() - } + req, _ := snap.NewCreditCard(inv) assert.Len(t, req.EnabledPayments, 1) assert.Equal(t, int64(7000), req.TransactionDetails.GrossAmt) assert.Equal(t, 2, len(*req.Items)) - assert.Contains(t, req.EnabledPayments, gomidtrans.SourceCreditCard) + assert.Contains(t, req.EnabledPayments, midsnap.PaymentTypeCreditCard) assert.True(t, req.CreditCard.Secure) assert.Equal(t, "bca", req.CreditCard.Bank) - assert.Equal(t, "3ds", req.CreditCard.Authentication) assert.True(t, req.CreditCard.Installment.Required) assert.Contains(t, req.CreditCard.Installment.Terms.Offline, int8(3)) assert.Empty(t, req.CreditCard.Installment.Terms.Bni) diff --git a/gateway/midtrans/snap/gopay.go b/gateway/midtrans/snap/gopay.go new file mode 100644 index 0000000..b0e7437 --- /dev/null +++ b/gateway/midtrans/snap/gopay.go @@ -0,0 +1,13 @@ +package snap + +import ( + "github.com/midtrans/midtrans-go/snap" + + "github.com/imrenagi/go-payment/invoice" +) + +func NewGopay(inv *invoice.Invoice) (*snap.Request, error) { + return newBuilder(inv). + AddPaymentMethods(snap.PaymentTypeGopay). + Build() +} diff --git a/gateway/midtrans/snap/gopay_test.go b/gateway/midtrans/snap/gopay_test.go new file mode 100644 index 0000000..8a9c746 --- /dev/null +++ b/gateway/midtrans/snap/gopay_test.go @@ -0,0 +1,97 @@ +package snap_test + +import ( + "testing" + + "github.com/midtrans/midtrans-go" + midsnap "github.com/midtrans/midtrans-go/snap" + "github.com/stretchr/testify/assert" + + . "github.com/imrenagi/go-payment/gateway/midtrans/snap" + "github.com/imrenagi/go-payment/invoice" +) + +func TestNewGopay(t *testing.T) { + + tests := []struct { + name string + inv *invoice.Invoice + req *midsnap.Request + wantErr error + }{ + { + name: "successfully create gopay request", + inv: dummyInv, + req: &midsnap.Request{ + TransactionDetails: midtrans.TransactionDetails{ + OrderID: "a-random-invoice-number", + GrossAmt: 15700, + }, + Items: &[]midtrans.ItemDetails{ + { + ID: "1", + Name: "random-item", + Price: 15000, + Qty: 1, + Category: "HOME", + }, + { + ID: "adminfee", + Name: "Biaya Admin", + Price: 500, + Qty: 1, + Category: "FEE", + }, + { + ID: "installmentfee", + Name: "Installment Fee", + Price: 1000, + Qty: 1, + Category: "FEE", + }, + { + ID: "discount", + Name: "Discount", + Price: -1000, + Qty: 1, + Category: "DISCOUNT", + }, + { + ID: "tax", + Name: "Tax", + Price: 200, + Qty: 1, + Category: "TAX", + }, + }, + CustomerDetail: &midtrans.CustomerDetails{ + FName: "John Doe", + LName: "", + Email: "foo@bar.com", + Phone: "08111231234", + BillAddr: &midtrans.CustomerAddress{ + FName: "John Doe", + LName: "", + Phone: "08111231234", + }, + }, + EnabledPayments: []midsnap.SnapPaymentType{ + midsnap.PaymentTypeGopay, + }, + Expiry: &midsnap.ExpiryDetails{ + StartTime: "2021-01-01 07:00:00 +0700", + Unit: "hour", + Duration: 24, + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + req, err := NewGopay(tt.inv) + assert.Equal(t, tt.wantErr, err) + assert.EqualValues(t, tt.req, req) + }) + } +} diff --git a/gateway/midtrans/snap/mandiri.go b/gateway/midtrans/snap/mandiri.go new file mode 100644 index 0000000..2a68a69 --- /dev/null +++ b/gateway/midtrans/snap/mandiri.go @@ -0,0 +1,13 @@ +package snap + +import ( + "github.com/midtrans/midtrans-go/snap" + + "github.com/imrenagi/go-payment/invoice" +) + +func NewMandiriVA(inv *invoice.Invoice) (*snap.Request, error) { + return newBuilder(inv). + AddPaymentMethods(snap.PaymentTypeEChannel). + Build() +} diff --git a/gateway/midtrans/snap/mandiri_test.go b/gateway/midtrans/snap/mandiri_test.go new file mode 100644 index 0000000..3f2301e --- /dev/null +++ b/gateway/midtrans/snap/mandiri_test.go @@ -0,0 +1,40 @@ +package snap_test + +import ( + "testing" + + midsnap "github.com/midtrans/midtrans-go/snap" + "github.com/stretchr/testify/assert" + + "github.com/imrenagi/go-payment/gateway/midtrans/snap" + "github.com/imrenagi/go-payment/invoice" +) + +func TestNewMandiriVA(t *testing.T) { + type args struct { + inv *invoice.Invoice + } + tests := []struct { + name string + args args + want *midsnap.Request + wantErr error + }{ + { + name: "standard mandiri va request", + args: args{inv: dummyInv}, + want: &midsnap.Request{ + EnabledPayments: []midsnap.SnapPaymentType{ + midsnap.PaymentTypeEChannel, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := snap.NewMandiriVA(tt.args.inv) + assert.Equal(t, tt.wantErr, err) + assert.Contains(t, got.EnabledPayments, midsnap.PaymentTypeEChannel) + }) + } +} diff --git a/gateway/midtrans/snap/other_bank.go b/gateway/midtrans/snap/other_bank.go new file mode 100644 index 0000000..3836994 --- /dev/null +++ b/gateway/midtrans/snap/other_bank.go @@ -0,0 +1,13 @@ +package snap + +import ( + "github.com/midtrans/midtrans-go/snap" + + "github.com/imrenagi/go-payment/invoice" +) + +func NewOtherBankVA(inv *invoice.Invoice) (*snap.Request, error) { + return newBuilder(inv). + AddPaymentMethods(snap.PaymentTypeOtherVA). + Build() +} diff --git a/gateway/midtrans/snap/other_bank_test.go b/gateway/midtrans/snap/other_bank_test.go new file mode 100644 index 0000000..c098407 --- /dev/null +++ b/gateway/midtrans/snap/other_bank_test.go @@ -0,0 +1,40 @@ +package snap_test + +import ( + "testing" + + midsnap "github.com/midtrans/midtrans-go/snap" + "github.com/stretchr/testify/assert" + + "github.com/imrenagi/go-payment/gateway/midtrans/snap" + "github.com/imrenagi/go-payment/invoice" +) + +func TestNewOtherBankVA(t *testing.T) { + type args struct { + inv *invoice.Invoice + } + tests := []struct { + name string + args args + want *midsnap.Request + wantErr error + }{ + { + name: "standard other bank va request", + args: args{inv: dummyInv}, + want: &midsnap.Request{ + EnabledPayments: []midsnap.SnapPaymentType{ + midsnap.PaymentTypeOtherVA, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := snap.NewOtherBankVA(tt.args.inv) + assert.Equal(t, tt.wantErr, err) + assert.Contains(t, got.EnabledPayments, midsnap.PaymentTypeOtherVA) + }) + } +} diff --git a/gateway/midtrans/snap/permata.go b/gateway/midtrans/snap/permata.go new file mode 100644 index 0000000..8540571 --- /dev/null +++ b/gateway/midtrans/snap/permata.go @@ -0,0 +1,13 @@ +package snap + +import ( + "github.com/midtrans/midtrans-go/snap" + + "github.com/imrenagi/go-payment/invoice" +) + +func NewPermataVA(inv *invoice.Invoice) (*snap.Request, error) { + return newBuilder(inv). + AddPaymentMethods(snap.PaymentTypePermataVA). + Build() +} diff --git a/gateway/midtrans/snap/permata_test.go b/gateway/midtrans/snap/permata_test.go new file mode 100644 index 0000000..18a445b --- /dev/null +++ b/gateway/midtrans/snap/permata_test.go @@ -0,0 +1,41 @@ +package snap_test + +import ( + "testing" + + midsnap "github.com/midtrans/midtrans-go/snap" + "github.com/stretchr/testify/assert" + + "github.com/imrenagi/go-payment/gateway/midtrans/snap" + "github.com/imrenagi/go-payment/invoice" +) + +func TestNewPermataVA(t *testing.T) { + type args struct { + inv *invoice.Invoice + } + tests := []struct { + name string + args args + want *midsnap.Request + wantErr error + }{ + { + name: "standard permata va request", + args: args{inv: dummyInv}, + want: &midsnap.Request{ + EnabledPayments: []midsnap.SnapPaymentType{ + midsnap.PaymentTypePermataVA, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := snap.NewPermataVA(tt.args.inv) + assert.Equal(t, tt.wantErr, err) + assert.EqualValues(t, tt.want.PermataVa, got.PermataVa) + assert.Contains(t, got.EnabledPayments, midsnap.PaymentTypePermataVA) + }) + } +} diff --git a/gateway/midtrans/snap/shopeepay.go b/gateway/midtrans/snap/shopeepay.go new file mode 100644 index 0000000..ab1a6d1 --- /dev/null +++ b/gateway/midtrans/snap/shopeepay.go @@ -0,0 +1,13 @@ +package snap + +import ( + midsnap "github.com/midtrans/midtrans-go/snap" + + "github.com/imrenagi/go-payment/invoice" +) + +func NewShopeePay(inv *invoice.Invoice) (*midsnap.Request, error) { + return newBuilder(inv). + AddPaymentMethods(midsnap.PaymentTypeShopeepay). + Build() +} diff --git a/gateway/midtrans/snap/shopeepay_test.go b/gateway/midtrans/snap/shopeepay_test.go new file mode 100644 index 0000000..a6bea55 --- /dev/null +++ b/gateway/midtrans/snap/shopeepay_test.go @@ -0,0 +1,41 @@ +package snap_test + +import ( + "testing" + + midsnap "github.com/midtrans/midtrans-go/snap" + "github.com/stretchr/testify/assert" + + "github.com/imrenagi/go-payment/gateway/midtrans/snap" + "github.com/imrenagi/go-payment/invoice" +) + +func TestNewShopeePay(t *testing.T) { + type args struct { + inv *invoice.Invoice + } + tests := []struct { + name string + args args + want *midsnap.Request + wantErr error + }{ + { + name: "standard shopeepay request", + args: args{inv: dummyInv}, + want: &midsnap.Request{ + EnabledPayments: []midsnap.SnapPaymentType{ + midsnap.PaymentTypeShopeepay, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := snap.NewShopeePay(tt.args.inv) + assert.Equal(t, tt.wantErr, err) + assert.EqualValues(t, tt.want.ShopeePay, got.ShopeePay) + assert.Contains(t, got.EnabledPayments, midsnap.PaymentTypeShopeepay) + }) + } +} diff --git a/go.mod b/go.mod index f45afde..92dab9a 100644 --- a/go.mod +++ b/go.mod @@ -6,17 +6,15 @@ require ( github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927 // indirect github.com/google/uuid v1.1.1 github.com/gorilla/mux v1.7.4 + github.com/midtrans/midtrans-go v1.2.1 github.com/rs/cors v1.7.0 github.com/rs/zerolog v1.18.0 github.com/spf13/viper v1.6.2 github.com/stretchr/objx v0.2.0 // indirect - github.com/stretchr/testify v1.6.0 - github.com/veritrans/go-midtrans v0.0.0-20200303064216-54da2d269748 + github.com/stretchr/testify v1.7.0 github.com/xendit/xendit-go v0.8.0 golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4 // indirect gopkg.in/yaml.v2 v2.2.8 gorm.io/driver/sqlite v1.1.4 gorm.io/gorm v1.21.11 ) - -replace github.com/veritrans/go-midtrans v0.0.0-20200303064216-54da2d269748 => github.com/schoters/go-midtrans v0.0.0-20200301123106-412075ea875d diff --git a/go.sum b/go.sum index 4832add..a927836 100644 --- a/go.sum +++ b/go.sum @@ -84,6 +84,8 @@ github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czP github.com/mattn/go-sqlite3 v1.14.5 h1:1IdxlwTNazvbKJQSxoJ5/9ECbEeaTTyeU7sEAZ5KKTQ= github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/midtrans/midtrans-go v1.2.1 h1:kPzA1ell7RvGnbCWcwXmkpbUfQjTjmjXoa97IIa1zgA= +github.com/midtrans/midtrans-go v1.2.1/go.mod h1:5hN2oiZDP3/SwSBxHPTg8eC/RVoRE9DXQOY1Ah9au10= github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -140,10 +142,14 @@ github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.0 h1:jlIyCplCJFULU/01vCkhKuTyc3OorI3bJFuw6obfgho= github.com/stretchr/testify v1.6.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/veritrans/go-midtrans v0.0.0-20210616100512-16326c5eeb00 h1:iCcVFY2mUdalvtpNN0M/vcf7+OYHGKXwzG5JLZgjwQU= +github.com/veritrans/go-midtrans v0.0.0-20210616100512-16326c5eeb00/go.mod h1:21mwYsDK+z+5kR2fvUB8n2yijZZm504Vjzk1s0rNQJg= github.com/xendit/xendit-go v0.4.1-0.20201006160855-28eaa35b35d5 h1:YDeZT9+vREUeVgY+B9LmS7l1ZEH+vLQ7Mm7rY1ImkuA= github.com/xendit/xendit-go v0.4.1-0.20201006160855-28eaa35b35d5/go.mod h1:LoyNAWrlHh68e4pguT3KmQzphY1nlQGlSRcMdzp6ARo= github.com/xendit/xendit-go v0.8.0 h1:2NKVSzSlLDEFZwEgrpTx8QPe4DzXKiglAhHpMJWfFbE= diff --git a/manage/charger.go b/manage/charger.go index 082798f..0268d17 100644 --- a/manage/charger.go +++ b/manage/charger.go @@ -25,27 +25,32 @@ type midtransCharger struct { func (c midtransCharger) Create(ctx context.Context, inv *invoice.Invoice) (*invoice.ChargeResponse, error) { - snapRequest, err := midfactory.NewSnapRequestFromInvoice(inv) + l := log.Ctx(ctx).With(). + Str("function", "midtransCharger.Create"). + Str("invoice_number", inv.Number). + Logger() + + snapRequest, err := midfactory.NewSnapFromInvoice(inv) if err != nil { return nil, err } - // bytes, err := json.MarshalIndent(snapRequest, "", "\t") - // if err != nil { - // return nil, err - // } - // fmt.Println(string(bytes)) - - resp, err := c.MidtransGateway.SnapGateway.GetToken(snapRequest) + bytes, err := json.MarshalIndent(snapRequest, "", "\t") if err != nil { return nil, err } + l.Debug(). + RawJSON("payload", bytes). + Msg("snap request is created") + + resp, mErr := c.MidtransGateway.SnapV2Gateway.CreateTransaction(snapRequest) + if mErr != nil { + return nil, err + } return &invoice.ChargeResponse{ PaymentToken: resp.Token, PaymentURL: resp.RedirectURL, - // TransactionID: resp. - }, nil } diff --git a/manage/manage.go b/manage/manage.go index 28e1f2c..d221f3d 100644 --- a/manage/manage.go +++ b/manage/manage.go @@ -6,12 +6,12 @@ import ( "fmt" "time" - "github.com/imrenagi/go-payment/subscription" + "github.com/midtrans/midtrans-go/coreapi" "github.com/imrenagi/go-payment" "github.com/imrenagi/go-payment/gateway/xendit" "github.com/imrenagi/go-payment/invoice" - mgo "github.com/veritrans/go-midtrans" + "github.com/imrenagi/go-payment/subscription" ) // GenerateInvoiceRequest provide to generate new invoice @@ -51,7 +51,7 @@ type FailInvoiceRequest struct { } // CreateSubscriptionRequest contains data for creating subscription -type CreateSubscriptionRequest struct { +type CreateSubscriptionRequest struct { Name string `json:"name"` Description string `json:"description"` Amount float64 `json:"amount"` @@ -167,7 +167,7 @@ type XenditProcessor interface { // MidtransProcessor callback handler for midtrans type MidtransProcessor interface { - ProcessMidtransCallback(ctx context.Context, mr mgo.Response) error + ProcessMidtransCallback(ctx context.Context, mr *coreapi.TransactionStatusResponse) error } // Payment combines all interface used for payment manager diff --git a/manage/midtrans.go b/manage/midtrans.go index 6b86bb7..4a33702 100644 --- a/manage/midtrans.go +++ b/manage/midtrans.go @@ -5,15 +5,16 @@ import ( "errors" "time" + "github.com/midtrans/midtrans-go/coreapi" + "github.com/rs/zerolog" + "github.com/imrenagi/go-payment" "github.com/imrenagi/go-payment/gateway/midtrans" - "github.com/rs/zerolog" - midgo "github.com/veritrans/go-midtrans" ) // ProcessMidtransCallback takes care of notification sent by midtrans. This checks the validity of the sign key and the similarity // between the notification and transaction satus. -func (m *Manager) ProcessMidtransCallback(ctx context.Context, mr midgo.Response) error { +func (m *Manager) ProcessMidtransCallback(ctx context.Context, mr *coreapi.TransactionStatusResponse) error { log := zerolog.Ctx(ctx). With(). @@ -46,7 +47,7 @@ func (m *Manager) ProcessMidtransCallback(ctx context.Context, mr midgo.Response storedStatus = &midtrans.TransactionStatus{ StatusCode: mr.StatusCode, StatusMessage: mr.StatusMessage, - SignKey: mr.SignKey, + SignKey: mr.SignatureKey, Bank: mr.Bank, FraudStatus: mr.FraudStatus, PaymentType: mr.PaymentType, @@ -65,7 +66,7 @@ func (m *Manager) ProcessMidtransCallback(ctx context.Context, mr midgo.Response storedStatus.StatusMessage = mr.StatusMessage storedStatus.GrossAmount = mr.GrossAmount storedStatus.FraudStatus = mr.FraudStatus - storedStatus.SignKey = mr.SignKey + storedStatus.SignKey = mr.SignatureKey storedStatus.TransactionTime = transactionTime storedStatus.TransactionStatus = mr.TransactionStatus storedStatus.TransactionID = mr.TransactionID diff --git a/server/server.go b/server/server.go index 5d5fa04..27770ee 100644 --- a/server/server.go +++ b/server/server.go @@ -5,14 +5,15 @@ import ( "net/http" "github.com/gorilla/mux" + "github.com/midtrans/midtrans-go/coreapi" + + "gorm.io/gorm" "github.com/imrenagi/go-payment" "github.com/imrenagi/go-payment/gateway/midtrans" "github.com/imrenagi/go-payment/gateway/xendit" "github.com/imrenagi/go-payment/invoice" "github.com/imrenagi/go-payment/manage" - "gorm.io/gorm" - mgo "github.com/veritrans/go-midtrans" ) func migrate(db *gorm.DB) { @@ -156,7 +157,7 @@ func (s Server) ResumeSubscriptionHandler() http.HandlerFunc { func (s *Server) MidtransTransactionCallbackHandler() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { decoder := json.NewDecoder(r.Body) - var notification mgo.Response + var notification coreapi.TransactionStatusResponse err := decoder.Decode(¬ification) if err != nil { WriteFailResponse(w, http.StatusBadRequest, Error{ @@ -165,7 +166,7 @@ func (s *Server) MidtransTransactionCallbackHandler() http.HandlerFunc { }) return } - err = s.Manager.ProcessMidtransCallback(r.Context(), notification) + err = s.Manager.ProcessMidtransCallback(r.Context(), ¬ification) if err != nil { WriteFailResponseFromError(w, err) return