|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Objectorg.starhope.appius.sql.SQLPeerDatum
org.starhope.appius.mb.Payment
public class Payment
Fairly complete encapsulation of all things related to an individual payment.
Nested Class Summary | |
---|---|
static class |
Payment.ItemType
What type of item is paid-for? Every class implementing Invoiceable should be on this list. |
Field Summary | |
---|---|
private HashMap<String,String> |
annotations
The collection of additional annotations for record-keeping or other purposes. |
private boolean |
closed
Once this is set, no further setting is accepted to any internal fields: the payment record is closed out completely. |
private PaymentCredential |
credentials
The payment credentials presented. |
private int |
expiryMonth
WRITEME |
private int |
expiryYear
The year in which the credit-card used to pay for this transaction will expire. |
private Date |
firstTried
The time at which we first tried to post this payment. |
private long |
lastTried
The time at which we last tried to re-submit a pending transaction |
private String |
order_code
The order code is an unique string for this order among all orders placed through a specific source (payment gateway, generally) |
private String |
order_source
The order's source code is an identifier which maps to the payment gateway class, but is user-visible as a part of the total payment identifier (source, code, and sequence number) |
private BigDecimal |
paid
The amount actually paid with this payment. |
private String |
payer
The identification of the payer |
private String |
paymentFor
WRITEME |
private PaymentGatewayReal |
paymentGateway
Through what payment gateway was this payment processed? |
private BigDecimal |
price
The price paid in this payment |
private String |
resultReason
The reason for the failure (if it failed), or the authorization code for the success (if it succeeded) |
private int |
sequence
The sequence number indicates a series of payments that are related to the same event; this is (always, right now, but) typically a subscription recurring every month. |
private static long |
serialVersionUID
Java serialisation. |
private Timestamp |
stamp
The moment in time at which, per our accounting, this payment took place. |
private boolean |
success
Was the payment a success? We keep records of failed payments, too, so it's important to ask that question. |
private boolean |
testMode
Was this a test transaction, submitted by the system? It's possible. |
private BigDecimal |
transactionCode
The transaction code returned by the payment gateway |
private UserEnrolment |
userEnrolment
If this payment was made for an enrolment subscription (right now (TODO) they all are), then this stores the pointer to the UserEnrolment record in question. |
private boolean |
verified
True, if the payment has been reconciled or verified. |
Constructor Summary | |
---|---|
Payment()
Create a payment for which a subscription does not yet exist |
|
Payment(Class<AuthorizeNetGateway> gatewayClass,
HashMap<String,String> authorizeNetData)
Handle Silent Post data returned by Authorize.Net. |
|
Payment(ResultSet resultSet)
Instantiate a Payment from the results returned by an SQL statement. |
|
Payment(String orderSourceID,
String orderCodeString,
int paymentSequenceNumber)
Instantiate a copy of the Payment for a given order and sequence number. |
|
Payment(UserEnrolment subscription)
Create a new payment upon a given UserEnrolment |
Method Summary | |
---|---|
void |
addAnnotation(String key,
String value)
WRITEME: document this method (brpocock@star-hope.org, Jul 13, 2009) |
static Payment |
addPaymentToSequence(UserEnrolment userEnrolment)
Adds a new payment to the sequence for a User Enrolment. |
private void |
assertOpen()
|
void |
changed()
WRITEME twheys@gmail.com |
void |
close()
Close out the payment completely. |
void |
flush()
|
String |
getAnnotation(String key)
Retrieve a specific annotation made against a payment. |
String[] |
getAnnotationNames()
Retrieve an array of annotation names. |
protected String |
getCacheUniqueID()
This is an overriding method. |
PaymentCredential |
getCredentials()
Note: Credentials for payment are not saved to JSON or database. |
Currency |
getCurrency()
Get the currency with which this payment was/will be made |
int |
getExpiryMonth()
|
int |
getExpiryYear()
|
BigDecimal |
getGatewayTransactionCode()
|
static Payment |
getLastPaymentFor(UserEnrolment userEnrolment)
Find the last/latest payment made on a specific enrolment |
BigDecimal |
getPaid()
|
String |
getPayer()
|
String |
getPayment_for()
Deprecated. |
String |
getPaymentFor()
|
PaymentGateway |
getPaymentGateway()
|
BigDecimal |
getPrice()
|
Payment |
getPriorPayment()
|
String |
getResultReason()
|
Date |
getRetryTime()
If this payment is pending, and we're holding credentials in core, we need to figure out how long before we try again. |
int |
getSequence()
|
Date |
getStamp()
|
Payment |
getStatusFromGateway()
FIXME ... |
UserEnrolment |
getUserEnrolment()
|
private void |
init(String orderSourceID,
String orderCodeString,
int paymentSequenceNumber)
|
boolean |
isClosed()
|
boolean |
isCompleted()
|
boolean |
isSuccess()
|
boolean |
isTest()
|
boolean |
isVerified()
|
void |
prepareForRetry(RetryPaymentException retryPaymentException)
If a payment should retry processing in future (e.g. |
protected void |
set(ResultSet rs)
|
void |
setCredentials(PaymentCredential paymentCredentials)
|
void |
setExpiryMonth(int expiryMonth1)
|
void |
setExpiryYear(int expiryYear1)
|
void |
setGatewayTransactionCode(BigDecimal transactionCodeNumber)
|
void |
setPaid(BigDecimal paid1)
|
void |
setPayer(String newPayer)
|
void |
setPayment_for(String payment_for1)
Deprecated. |
void |
setPaymentFor(String payment_for1)
|
void |
setPaymentGateway(PaymentGatewayReal paymentGatewayReal)
|
void |
setPrice(BigDecimal price1)
|
void |
setResultReason(String resultReason1)
|
void |
setSequence(int sequence1)
|
void |
setSuccess(boolean success1)
Note: Once this routine has been called, most of the setters in this Payment will refuse to operate. |
void |
setTest(boolean testMode1)
|
void |
setVerified(boolean verified1)
|
boolean |
shouldRetry()
|
void |
shredCredentials()
Destroy the credentials utterly, once and for all. |
void |
stamp()
WRITEME: document this method (brpocock@star-hope.org, Oct 13, 2009) |
org.json.JSONObject |
toJSON()
Note, we do not save credentials to any kind of stream or storage (JSON, SQL, &c.). |
String |
toString()
|
Methods inherited from class org.starhope.appius.sql.SQLPeerDatum |
---|
compareTo, findInCache, get, saveInCache, set |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
Field Detail |
---|
private static final long serialVersionUID
private HashMap<String,String> annotations
The collection of additional annotations for record-keeping or other purposes. These are things not used by the system, but which are tracked in case they're useful for human review, auditing, etc.
Annotations are keyed off dotted domain sequences in the same general fashion as Java class names, etc.
private boolean closed
private transient PaymentCredential credentials
private int expiryMonth
private int expiryYear
private transient Date firstTried
The time at which we first tried to post this payment. If a temporary problem was encountered, we can hold on to it (in core) and retry for a while, until a (configured) timeout has been reached.
This field is not persistent.
private transient long lastTried
private String order_code
private String order_source
private BigDecimal paid
private String payer
private String paymentFor
private PaymentGatewayReal paymentGateway
private BigDecimal price
private String resultReason
private int sequence
private Timestamp stamp
private boolean success
private boolean testMode
true
, we shouldn't give out
anything because of it.
private BigDecimal transactionCode
private UserEnrolment userEnrolment
private boolean verified
Constructor Detail |
---|
public Payment()
public Payment(Class<AuthorizeNetGateway> gatewayClass, HashMap<String,String> authorizeNetData)
gatewayClass
- The class responsible for this payment;
should always be AuthorizeNetGateway for now. Provides
an easy hook to make sure we're in the right place,
not processing e.g. PayPal data here.authorizeNetData
- The key:value pairs of the data from
Authorize.Netpublic Payment(ResultSet resultSet) throws SQLException
resultSet
- The SQL ResultSet with the cursor currently on
the row from which this Payment is to be instantiated.
SQLException
- if we can't cooperate with the database.
Note that we initiate a secondary query on the same
connection to obtain annotations, so there is more
happening here than just fetching results from the
existing ResultSet. If, for example, the connection
were closed in between retrieving the ResultSet
including this payment and instantiating it, it would
throw some SQL exceptions related to that failure.public Payment(String orderSourceID, String orderCodeString, int paymentSequenceNumber) throws NotFoundException
orderSourceID
- The payment gateway originating the orderorderCodeString
- The unique order codepaymentSequenceNumber
- The sequence number
NotFoundException
- if the payment cant't be found.public Payment(UserEnrolment subscription)
subscription
- WRITEMEMethod Detail |
---|
public static Payment addPaymentToSequence(UserEnrolment userEnrolment) throws NotFoundException
userEnrolment
- The user enrolment to add a payment to.
NotFoundException
- If the last payment cannot be found.public static Payment getLastPaymentFor(UserEnrolment userEnrolment) throws NotFoundException
userEnrolment
- the enrolment (subscription) object
NotFoundException
- if there are no payments madepublic void addAnnotation(String key, String value) throws AlreadyUsedException
key
- The annotation's key (in inverse-dotted notation)value
- The value for this annotation
AlreadyUsedException
- if the annotation existsannotations
private void assertOpen() throws AlreadyUsedException
AlreadyUsedException
- if the payment has been postedpublic void changed()
changed
in class SQLPeerDatum
public void close() throws SQLException
setSuccess(boolean)
, the payment enters a state of
“closing out” for post-processing details only to be added to it.
Once this routine is called, the payment is totally frozen.
SQLException
- WRITEMEpublic void flush()
flush
in class SQLPeerDatum
SQLPeerDatum.flush()
public String getAnnotation(String key)
key
- the ID of the annotation
public String[] getAnnotationNames()
protected String getCacheUniqueID()
getCacheUniqueID
in class SQLPeerDatum
SQLPeerDatum.getCacheUniqueID()
public PaymentCredential getCredentials()
Note: Credentials for payment are not saved to JSON or database. As such, they only persist as long as they're held in-core.
For this reason, we need to hold on to pending payments' references to avoid potential GC. We cannot re-instantiate a non-completed payment from the database.
This is an intentional security precaution.
public Currency getCurrency()
As with many things, this is still hardcoded as USD.
public int getExpiryMonth()
public int getExpiryYear()
public BigDecimal getGatewayTransactionCode()
public BigDecimal getPaid()
public String getPayer()
@Deprecated public String getPayment_for()
getPaymentFor()
instead
public String getPaymentFor()
public PaymentGateway getPaymentGateway()
public BigDecimal getPrice()
public Payment getPriorPayment() throws NotFoundException
NotFoundException
- if there wasn't a prior sequence
payment.public String getResultReason()
public Date getRetryTime() throws AlreadyUsedException, DataException
If this payment is pending, and we're holding credentials in core, we need to figure out how long before we try again. In the spirit of exponential back-off, we'll try every 1 minute for the first 10 minutes, then back off to every 5 minutes for the next 50 minutes, after which we'll go to every 15 minutes until it's been 12 hours, after which time, we'll try every hour until the payment record is dropped.
Note that we need to keep a hard reference to this Payment in the timer routine handling re-submissions, because if the Payment record is purged from the cache, we lose the credentials. This is intentional: we don't want to keep credentials lying around, ever.
AlreadyUsedException
- if the payment can't be retried
DataException
- if there are no payment credentials
available for retryingpublic int getSequence()
public Date getStamp()
public Payment getStatusFromGateway()
public UserEnrolment getUserEnrolment()
private void init(String orderSourceID, String orderCodeString, int paymentSequenceNumber) throws NotFoundException
orderSourceID
- WRITEMEorderCodeString
- WRITEMEpaymentSequenceNumber
- WRITEME
NotFoundException
- WRITEMEpublic boolean isClosed()
closed
public boolean isCompleted()
public boolean isSuccess()
public boolean isTest()
public boolean isVerified()
public void prepareForRetry(RetryPaymentException retryPaymentException) throws AlreadyUsedException, DataException
retryPaymentException
- the exception causing this to be
scheduled for a do-over
DataException
- ...
AlreadyUsedException
- ...protected void set(ResultSet rs)
set
in class SQLPeerDatum
rs
- The result of an SQL query, with the cursor already
pointed at the row describing this specific instance of
the object.SQLPeerDatum.set(java.sql.ResultSet)
public void setCredentials(PaymentCredential paymentCredentials) throws AlreadyUsedException
paymentCredentials
- the credentials to set
AlreadyUsedException
- if the payment is closedpublic void setExpiryMonth(int expiryMonth1)
expiryMonth1
- the expiryMonth to setpublic void setExpiryYear(int expiryYear1)
expiryYear1
- the expiryYear to setpublic void setGatewayTransactionCode(BigDecimal transactionCodeNumber) throws AlreadyUsedException
transactionCodeNumber
- the transaction code number returned
by the payment gateway
AlreadyUsedException
- if this payment has already gotten a
transaction numberpublic void setPaid(BigDecimal paid1)
paid1
- the amount paidpublic void setPayer(String newPayer)
newPayer
- The payer for this payment@Deprecated public void setPayment_for(String payment_for1)
setPaymentFor(String)
instead.
payment_for1
- WRITEMEpublic void setPaymentFor(String payment_for1)
payment_for1
- the payment_for to setpublic void setPaymentGateway(PaymentGatewayReal paymentGatewayReal) throws AlreadyUsedException
paymentGatewayReal
- Set the payment gateway through which
this payment was made
AlreadyUsedException
- if the payment has already been madepublic void setPrice(BigDecimal price1)
price1
- the price to setpublic void setResultReason(String resultReason1)
resultReason1
- the failedReason to setpublic void setSequence(int sequence1)
sequence1
- the sequence to setpublic void setSuccess(boolean success1)
Note: Once this routine has been called, most of
the setters in this Payment will refuse to operate. It will begin
closing-out. Only post-transaction setters will work, and they
will stop working once close()
is called.
This also causes the Payment object to permanently discard the credentials used for payment.
success1
- true if the payment succeeded, false otherwise.public void setTest(boolean testMode1) throws AlreadyUsedException
testMode1
- If true, then this is meant to be a test
transaction, and not a real payment.
AlreadyUsedException
- if this payment has progressed too
far to be marked as a test nowpublic void setVerified(boolean verified1)
verified1
- the verified to setpublic boolean shouldRetry()
public void shredCredentials()
public void stamp()
public org.json.JSONObject toJSON()
Note, we do not save credentials to any kind of stream or storage (JSON, SQL, &c.). Likewise, firstTried is useless in future, since it's only useful in concert with credentials for orders that need a retry.
toJSON
in class SQLPeerDatum
SQLPeerDatum.toJSON()
public String toString()
toString
in class Object
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |