Skip to content

Commit

Permalink
Bumped to v0.3.0 (#2)
Browse files Browse the repository at this point in the history
- Add TransactionSearch API
- Move merchant to client/merchant
  • Loading branch information
evalphobia authored Jan 17, 2017
1 parent af4fdc1 commit 715a677
Show file tree
Hide file tree
Showing 25 changed files with 414 additions and 208 deletions.
40 changes: 34 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ go-paypal-classic is library for [PayPal Classic API](https://developer.paypal.c
- [GetRecurringPaymentsProfileDetails](https://developer.paypal.com/docs/classic/api/merchant/GetRecurringPaymentsProfileDetails_API_Operation_NVP/)
- [ManageRecurringPaymentsProfileStatus](https://developer.paypal.com/docs/classic/api/merchant/ManageRecurringPaymentsProfileStatus_API_Operation_NVP/)
- [SetExpressCheckout](https://developer.paypal.com/docs/classic/api/merchant/SetExpressCheckout_API_Operation_NVP/)
- Transaction
- [TransactionSearch](https://developer.paypal.com/docs/classic/api/merchant/TransactionSearch_API_Operation_NVP/)

## Quick Usage

Expand All @@ -42,7 +44,7 @@ import (
"os"

"github.com/evalphobia/go-paypal-classic/config"
"github.com/evalphobia/go-paypal-classic/merchant"
"github.com/evalphobia/go-paypal-classic/client/merchant"
)

func main() {
Expand Down Expand Up @@ -75,7 +77,7 @@ func main() {

```go
import (
"github.com/evalphobia/go-paypal-classic/merchant"
"github.com/evalphobia/go-paypal-classic/client/merchant"
)

func main() {
Expand All @@ -99,7 +101,7 @@ func main() {

```go
import (
"github.com/evalphobia/go-paypal-classic/merchant"
"github.com/evalphobia/go-paypal-classic/client/merchant"
)

func main() {
Expand All @@ -126,7 +128,7 @@ func main() {

```go
import (
"github.com/evalphobia/go-paypal-classic/merchant"
"github.com/evalphobia/go-paypal-classic/client/merchant"
)

func main() {
Expand Down Expand Up @@ -156,7 +158,7 @@ func main() {

```go
import (
"github.com/evalphobia/go-paypal-classic/merchant"
"github.com/evalphobia/go-paypal-classic/client/merchant"
)

func main() {
Expand All @@ -179,7 +181,7 @@ func main() {

```go
import (
"github.com/evalphobia/go-paypal-classic/merchant"
"github.com/evalphobia/go-paypal-classic/client/merchant"
)

func main() {
Expand All @@ -199,3 +201,29 @@ func main() {
}
}
```

### TransactionSearch

```go
import (
"time"

"github.com/evalphobia/go-paypal-classic/client/transaction"
)

func main() {
ts = &transaction.TransactionSearch{
StartDate: time.Now(),
ProfileID: "I-000000000000",
}
resp, err := ts.Do(cli)
if err != nil {
panic("error occured on TransactionSearch api request")
}

if resp.IsSuccess() {
// transaction list
// resp.Items
}
}
```
17 changes: 14 additions & 3 deletions merchant/base.go → client/base.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package merchant
package client

import (
"strings"
)

// ACK statuses.
const (
ACKSuccess = "Success"
ACKFailure = "Failure"
)

// BaseRequest is base struct for api request
type BaseRequest struct {
Method string `url:"METHOD"`
Expand Down Expand Up @@ -31,6 +37,11 @@ type BaseResponse struct {
SeverityCode1 string `url:"L_SEVERITYCODE1"`
}

// IsRequestSuccess checks the request is success or not.
func (r BaseResponse) IsRequestSuccess() bool {
return r.ACK == ACKSuccess
}

func (r BaseResponse) baseError() []string {
var errs []string
if r.ShortMessage != "" {
Expand Down Expand Up @@ -58,8 +69,8 @@ func parseErrors(errs []string) string {
return strings.Join(errs, ",")
}

// MerchantResponse is interface of response from each API
type MerchantResponse interface {
// Response is interface of response from each API
type Response interface {
IsSuccess() bool
IsRequestSuccess() bool
IsOperationSuccess() bool
Expand Down
56 changes: 56 additions & 0 deletions client/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package client

import (
"github.com/evalphobia/go-paypal-classic/config"
"github.com/evalphobia/go-paypal-classic/request"
)

const (
endpointSandbox = "https://api-3t.sandbox.paypal.com/nvp"
endpointProduction = "https://api-3t.paypal.com/nvp"

redirectSandbox = "https://www.sandbox.paypal.com/webscr"
redirectProduction = "https://www.paypal.com/webscr"
)

// Client is base struct for PayPal Classic API
type Client struct {
Config *config.Config `url:",squash"`
}

// New creates Client with given config
func New(conf *config.Config) Client {
return Client{
Config: conf,
}
}

// NewDefault creates Client with default config
func NewDefault() Client {
return New(config.DefaultConfig)
}

// Call sends HTTP request to PayPal api.
func (c Client) Call(param interface{}, result interface{}) error {
p := parameter{
Common: c,
Extra: param,
}
if c.Config.IsProduction() {
return request.CallPOST(endpointProduction, p, result)
}
return request.CallPOST(endpointSandbox, p, result)
}

type parameter struct {
Common Client `url:",squash"`
Extra interface{} `url:",squash"`
}

// RedirectBase returns base url of PayPal ExpressCheckout
func (c Client) RedirectBase() string {
if c.Config.IsProduction() {
return redirectProduction
}
return redirectSandbox
}
2 changes: 1 addition & 1 deletion merchant/client_test.go → client/client_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package merchant
package client

import (
"testing"
Expand Down
13 changes: 13 additions & 0 deletions client/merchant/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package merchant

import (
"github.com/evalphobia/go-paypal-classic/client"
"github.com/evalphobia/go-paypal-classic/config"
)

// New creates client.Client with given config
func New(conf *config.Config) client.Client {
return client.Client{
Config: conf,
}
}
15 changes: 15 additions & 0 deletions merchant/currency.go → client/merchant/const.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
package merchant

import "github.com/evalphobia/go-paypal-classic/client"

const (
paymentActionSale = "sale"
payerStatusVerified = "verified"
itemCategoryDigital = "Digital"
billingTypeRecurring = "RecurringPayments"

statusActive = "Active"
profileActive = "ActiveProfile"
paymentStatusComleted = "Completed"

ackSuccess = client.ACKSuccess
)

// PayPal supported currencies
const (
CurrencyAUD = "AUD"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ package merchant

import (
"time"

"github.com/evalphobia/go-paypal-classic/client"
)

// CreateRecurringPaymentsProfile is struct for CreateRecurringPaymentsProfile API
// see: https://developer.paypal.com/docs/classic/api/merchant/CreateRecurringPaymentsProfile_API_Operation_NVP/
type CreateRecurringPaymentsProfile struct {
Merchant `url:",squash"`
BaseRequest `url:",squash"`
client.BaseRequest `url:",squash"`

BillingPeriod string `url:"BILLINGPERIOD"`
BillingFrequency int `url:"BILLINGFREQUENCY"`
Expand Down Expand Up @@ -64,25 +65,20 @@ func (svc *CreateRecurringPaymentsProfile) SetBillingStartDateFromNow() {
}
}

// SetMerchant sets Merchant
func (svc *CreateRecurringPaymentsProfile) SetMerchant(m Merchant) {
svc.Merchant = m
}

// Do executes CreateRecurringPaymentsProfile operation
func (svc *CreateRecurringPaymentsProfile) Do(m Merchant) (*CreateRecurringPaymentsProfileResponse, error) {
func (svc *CreateRecurringPaymentsProfile) Do(cli client.Client) (*CreateRecurringPaymentsProfileResponse, error) {
const method = "CreateRecurringPaymentsProfile"
svc.BaseRequest.Method = method
svc.BaseRequest.Action = paymentActionSale

result := &CreateRecurringPaymentsProfileResponse{}
err := m.call(svc, result)
err := cli.Call(svc, result)
return result, err
}

// CreateRecurringPaymentsProfileResponse is struct for response of CreateRecurringPaymentsProfile API
type CreateRecurringPaymentsProfileResponse struct {
BaseResponse `url:",squash"`
client.BaseResponse `url:",squash"`

// success
Token string `url:"TOKEN"`
Expand All @@ -95,11 +91,6 @@ func (r *CreateRecurringPaymentsProfileResponse) IsSuccess() bool {
return r.IsRequestSuccess() && r.IsOperationSuccess()
}

// IsRequestSuccess checks the request is success or not
func (r *CreateRecurringPaymentsProfileResponse) IsRequestSuccess() bool {
return r.ACK == ackSuccess
}

// IsOperationSuccess checks the request is success or not
func (r *CreateRecurringPaymentsProfileResponse) IsOperationSuccess() bool {
return r.ProfileStatus == profileActive
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@ import (
"testing"

"github.com/stretchr/testify/assert"

"github.com/evalphobia/go-paypal-classic/client"
)

func testNewDefault() client.Client {
return client.NewDefault()
}

func TestCreateRecurringPaymentsProfile(t *testing.T) {
assert := assert.New(t)

m := NewDefault()
cli := testNewDefault()

// error
svc := &CreateRecurringPaymentsProfile{
Expand All @@ -21,7 +27,7 @@ func TestCreateRecurringPaymentsProfile(t *testing.T) {
}
svc.SetPeriodAsMonth(13)
svc.SetBillingStartDateFromNow()
v, err := svc.Do(m)
v, err := svc.Do(cli)
assert.Nil(err)
assert.Equal("Failure", v.ACK)
assert.Equal("124", v.Version)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package merchant

import "github.com/evalphobia/go-paypal-classic/client"

// DoExpressCheckoutPayment is struct for DoExpressCheckoutPayment API
// see: https://developer.paypal.com/docs/classic/api/merchant/DoExpressCheckoutPayment_API_Operation_NVP/
type DoExpressCheckoutPayment struct {
Merchant `url:",squash"`
BaseRequest `url:",squash"`
client.BaseRequest `url:",squash"`

Token string `url:"TOKEN"`
PayerID string `url:"PAYERID"`
Expand All @@ -15,13 +16,8 @@ type DoExpressCheckoutPayment struct {
Currency string `url:"PAYMENTREQUEST_0_CURRENCYCODE"`
}

// SetMerchant sets Merchant
func (svc *DoExpressCheckoutPayment) SetMerchant(m Merchant) {
svc.Merchant = m
}

// Do executes DoExpressCheckoutPayment operation
func (svc *DoExpressCheckoutPayment) Do(m Merchant) (*DoExpressCheckoutPaymentResponse, error) {
func (svc *DoExpressCheckoutPayment) Do(cli client.Client) (*DoExpressCheckoutPaymentResponse, error) {
const method = "DoExpressCheckoutPayment"
svc.BaseRequest.Method = method
svc.BaseRequest.Action = paymentActionSale
Expand All @@ -31,13 +27,13 @@ func (svc *DoExpressCheckoutPayment) Do(m Merchant) (*DoExpressCheckoutPaymentRe
}

result := &DoExpressCheckoutPaymentResponse{}
err := m.call(svc, result)
err := cli.Call(svc, result)
return result, err
}

// DoExpressCheckoutPaymentResponse is struct for response of DoExpressCheckoutPayment API
type DoExpressCheckoutPaymentResponse struct {
BaseResponse `url:",squash"`
client.BaseResponse `url:",squash"`

// success
Token string `url:"TOKEN"`
Expand Down Expand Up @@ -75,11 +71,6 @@ func (r *DoExpressCheckoutPaymentResponse) IsSuccess() bool {
return r.IsRequestSuccess() && r.IsOperationSuccess()
}

// IsRequestSuccess checks the request is success or not
func (r *DoExpressCheckoutPaymentResponse) IsRequestSuccess() bool {
return r.ACK == ackSuccess
}

// IsOperationSuccess checks the request is success or not
func (r *DoExpressCheckoutPaymentResponse) IsOperationSuccess() bool {
return r.PaymentACK == ackSuccess
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
func TestDoExpressCheckoutPayment(t *testing.T) {
assert := assert.New(t)

m := NewDefault()
cli := testNewDefault()

// error
svc := &DoExpressCheckoutPayment{
Expand All @@ -18,7 +18,7 @@ func TestDoExpressCheckoutPayment(t *testing.T) {
TotalAmount: 200.0,
Currency: CurrencyTWD,
}
v, err := svc.Do(m)
v, err := svc.Do(cli)
assert.Nil(err)
assert.Equal("Failure", v.ACK)
assert.Equal("124", v.Version)
Expand Down
Loading

0 comments on commit 715a677

Please sign in to comment.