Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
UCC
uccportal
Commits
928e0e1c
Commit
928e0e1c
authored
Jan 24, 2019
by
frekk
Browse files
added member payment metadata table
parent
fed18925
Changes
4
Hide whitespace changes
Inline
Side-by-side
gms/squarepay/admin.py
View file @
928e0e1c
from
django.utils.html
import
format_html
from
gms
import
admin
from
.models
import
CardPayment
from
.models
import
CardPayment
,
MembershipPayment
class
CardPaymentAdmin
(
admin
.
ModelAdmin
):
list_display
=
[
'amount'
,
'url_field'
,
'date_created'
,
'is_paid'
]
...
...
@@ -12,4 +12,8 @@ class CardPaymentAdmin(admin.ModelAdmin):
url_field
.
short_description
=
'Payment URL'
url_field
.
allow_tags
=
True
admin
.
site
.
register
(
CardPayment
,
CardPaymentAdmin
)
\ No newline at end of file
class
MembershipPaymentAdmin
(
CardPaymentAdmin
):
list_display
=
[
'amount'
,
'url_field'
,
'date_created'
,
'is_paid'
,
'membership'
]
admin
.
site
.
register
(
CardPayment
,
CardPaymentAdmin
)
admin
.
site
.
register
(
MembershipPayment
,
MembershipPaymentAdmin
)
gms/squarepay/models.py
View file @
928e0e1c
import
uuid
from
django.core.management.utils
import
get_random_secret_key
from
django.core.management.utils
import
get_random_string
from
django.db
import
models
from
django.urls
import
reverse
from
memberdb.models
import
Membership
,
make_token
class
CardPayment
(
models
.
Model
):
token
=
models
.
CharField
(
'Unique payment token'
,
max_length
=
64
,
editable
=
False
,
default
=
get_random_secret_key
)
description
=
models
.
CharField
(
'Description'
,
max_length
=
255
)
amount
=
models
.
IntegerField
(
'Amount in cents'
,
null
=
False
,
blank
=
False
)
idempotency_key
=
models
.
CharField
(
'Square Transactions API idempotency key'
,
max_length
=
64
,
editable
=
False
,
default
=
uuid
.
uuid1
)
idempotency_key
=
models
.
CharField
(
'Square Transactions API idempotency key'
,
max_length
=
64
,
default
=
uuid
.
uuid1
)
is_paid
=
models
.
BooleanField
(
'Has been paid'
,
blank
=
True
,
default
=
False
)
completed_url
=
models
.
CharField
(
'Redirect URL on success'
,
max_length
=
255
,
null
=
True
,
editable
=
False
)
dispense_synced
=
models
.
BooleanField
(
'Payment lodged in dispense'
,
blank
=
True
,
default
=
False
)
dispense_synced
=
models
.
BooleanField
(
'Payment logged in dispense'
,
blank
=
True
,
default
=
False
)
date_created
=
models
.
DateTimeField
(
'Date created'
,
auto_now_add
=
True
)
date_paid
=
models
.
DateTimeField
(
'Date paid (payment captured)'
,
null
=
True
,
blank
=
True
)
def
save
(
self
,
*
args
,
**
kwargs
):
# generate a token by default. maybe possible using default=...?
if
(
self
.
token
is
None
):
self
.
token
=
get_random_secret_key
()
super
().
save
(
*
args
,
**
kwargs
)
def
get_absolute_url
(
self
):
return
reverse
(
'squarepay:pay'
,
kwargs
=
{
'pk'
:
self
.
pk
,
'token'
:
self
.
token
})
\ No newline at end of file
return
reverse
(
'squarepay:pay'
,
kwargs
=
{
'pk'
:
self
.
pk
,
'token'
:
self
.
token
})
class
MembershipPayment
(
CardPayment
):
"""
Link the payment to a specific membership
"""
membership
=
models
.
ForeignKey
(
Membership
,
on_delete
=
models
.
CASCADE
,
related_name
=
'payments'
)
gms/squarepay/urls.py
View file @
928e0e1c
from
django.urls
import
path
from
.views
import
PaymentFormView
from
.views
import
PaymentFormView
,
MembershipPaymentView
app_name
=
'squarepay'
urlpatterns
=
[
path
(
'pay/<int:pk>/<str:token>/'
,
PaymentFormView
.
as_view
(),
name
=
'pay'
),
]
\ No newline at end of file
#path('pay/<int:pk>/<str:token>/', PaymentFormView.as_view(), name='pay'),
path
(
'pay/<int:pk>/<str:token>/'
,
MembershipPaymentView
.
as_view
(),
name
=
'pay'
),
]
gms/squarepay/views.py
View file @
928e0e1c
import
uuid
from
django.views.generic.base
import
RedirectView
from
django.views.generic.detail
import
DetailView
from
django.http
import
HttpResponse
,
HttpResponseRedirect
,
Http404
from
django.contrib
import
messages
from
django.conf
import
settings
from
django.urls
import
reverse
from
django.utils
import
timezone
import
squareconnect
from
squareconnect.rest
import
ApiException
from
squareconnect.apis.transactions_api
import
TransactionsApi
from
squareconnect.apis.locations_api
import
LocationsApi
from
.models
import
CardPayment
from
.models
import
MembershipPayment
,
CardPayment
from
.
import
payments
from
.payments
import
try_capture_payment
,
set_paid
class
PaymentFormView
(
DetailView
):
"""
...
...
@@ -19,11 +19,6 @@ class PaymentFormView(DetailView):
template_name
=
'payment_form.html'
app_id
=
None
# square app ID (can be accessed by clients)
loc_id
=
None
# square location key (can also be accessed by clients)
access_key
=
None
# this is secret
sqapi
=
None
# keep an instance of the Square API handy
model
=
CardPayment
slug_field
=
'token'
slug_url_kwarg
=
'token'
...
...
@@ -33,51 +28,58 @@ class PaymentFormView(DetailView):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
().
__init__
(
*
args
,
**
kwargs
)
# get things from settings
self
.
app_id
=
getattr
(
settings
,
'SQUARE_APP_ID'
,
'bad_config'
)
self
.
loc_id
=
getattr
(
settings
,
'SQUARE_LOCATION'
,
'bad_config'
)
self
.
access_key
=
getattr
(
settings
,
'SQUARE_ACCESS_TOKEN'
)
# do some square API client stuff
self
.
sqapi
=
squareconnect
.
ApiClient
()
self
.
sqapi
.
configuration
.
access_token
=
self
.
access_key
def
get_context_data
(
self
,
**
kwargs
):
context
=
super
().
get_context_data
(
**
kwargs
)
amount
=
"$%1.2f AUD"
%
(
self
.
get_object
().
amount
/
100.0
)
context
.
update
({
'app_id'
:
self
.
app_id
,
'loc_id'
:
self
.
loc_id
,
'app_id'
:
payments
.
app_id
,
'loc_id'
:
payments
.
loc_id
,
'amount'
:
amount
,
})
return
context
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
nonce
=
request
.
POST
.
get
(
'nonce'
,
None
)
if
(
nonce
is
None
or
nonce
==
""
):
messages
.
error
(
request
,
"No nonce was generated! Please try reloading the page and submit again."
)
return
self
.
get
(
request
)
def
payment_success
(
self
,
payment
):
set_paid
(
payment
)
api_inst
=
TransactionsApi
(
self
.
sqapi
)
def
get_completed_url
(
self
):
return
self
.
get_object
().
get_absolute_url
()
body
=
{
'idempotency_key'
:
self
.
idempotency_key
,
'card_nonce'
:
nonce
,
'amount_money'
:
{
'amount'
:
amount
,
'currency'
:
'AUD'
}
}
def
post
(
self
,
request
,
*
args
,
**
kwargs
):
nonce
=
request
.
POST
.
get
(
'nonce'
,
None
)
card_payment
=
self
.
get_object
()
amount_aud
=
card_payment
.
amount
/
100.0
try
:
api_response
=
api_inst
.
charge
(
self
.
loc_id
,
body
)
messages
.
success
(
request
,
"Your payment of %1.2f was successful."
,
amount
)
except
ApiException
as
e
:
messages
.
error
(
request
,
"Exception while calling TransactionApi::charge: %s"
%
e
)
# redirect to success URL
if
(
self
.
object
.
completed_url
is
None
):
if
(
nonce
is
None
or
nonce
==
""
):
messages
.
error
(
request
,
"Failed to collect card details. Please reload the page and submit again."
)
return
self
.
get
(
request
)
return
HttpResponseRedirect
(
self
.
object
.
completed_url
)
if
try_capture_payment
(
card_payment
,
nonce
):
payment_success
(
card_payment
)
messages
.
success
(
request
,
"Your payment of $%1.2f was successful."
%
amount_aud
)
else
:
messages
.
error
(
request
,
"Your payment of $%1.2f was unsuccessful. Please try again later."
%
amount_aud
)
# redirect to success URL, or redisplay the form with a success message if none is given
return
HttpResponseRedirect
(
self
.
get_completed_url
())
class
MembershipPaymentView
(
PaymentFormView
):
model
=
MembershipPayment
def
dispatch
(
self
,
request
,
*
args
,
**
kwargs
):
self
.
object
=
self
.
get_object
()
if
(
self
.
object
.
membership
.
date_paid
is
not
None
):
# the membership is already marked as paid, so we add an error and redirect to member home
messages
.
error
(
request
,
"Your membership is already paid. Check the cokelog (/home/other/coke/cokelog) for more details."
)
return
HttpResponseRedirect
(
self
.
get_completed_url
())
else
:
return
super
().
dispatch
(
request
,
*
args
,
**
kwargs
)
def
payment_success
(
self
,
payment
):
ms
=
payment
.
membership
ms
.
date_paid
=
timezone
.
now
()
ms
.
payment_method
=
'online'
ms
.
save
()
super
().
payment_success
(
payment
)
def
get_completed_url
(
self
):
return
reverse
(
'memberdb:home'
)
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment