/** Returns the outputs of the payment request. */
 public List<PaymentProtocol.Output> getOutputs() {
   List<PaymentProtocol.Output> outputs =
       new ArrayList<PaymentProtocol.Output>(paymentDetails.getOutputsCount());
   for (Protos.Output output : paymentDetails.getOutputsList()) {
     Coin amount = output.hasAmount() ? Coin.valueOf(output.getAmount()) : null;
     outputs.add(new PaymentProtocol.Output(amount, output.getScript().toByteArray()));
   }
   return outputs;
 }
 @Test
 public void testDefaults() throws Exception {
   Protos.Output.Builder outputBuilder =
       Protos.Output.newBuilder().setScript(ByteString.copyFrom(outputToMe.getScriptBytes()));
   Protos.PaymentDetails paymentDetails =
       Protos.PaymentDetails.newBuilder().setTime(time).addOutputs(outputBuilder).build();
   Protos.PaymentRequest paymentRequest =
       Protos.PaymentRequest.newBuilder()
           .setSerializedPaymentDetails(paymentDetails.toByteString())
           .build();
   MockPaymentSession paymentSession = new MockPaymentSession(paymentRequest);
   assertEquals(BigInteger.ZERO, paymentSession.getValue());
   assertNull(paymentSession.getPaymentUrl());
   assertNull(paymentSession.getMemo());
 }
示例#3
0
 private Protos.PaymentRequest minimalPaymentRequest() {
   Protos.PaymentDetails.Builder paymentDetails = Protos.PaymentDetails.newBuilder();
   paymentDetails.setTime(System.currentTimeMillis());
   Protos.PaymentRequest.Builder paymentRequest = Protos.PaymentRequest.newBuilder();
   paymentRequest.setSerializedPaymentDetails(paymentDetails.build().toByteString());
   return paymentRequest.build();
 }
 /** Returns a {@link Wallet.SendRequest} suitable for broadcasting to the network. */
 public Wallet.SendRequest getSendRequest() {
   Transaction tx = new Transaction(params);
   for (Protos.Output output : paymentDetails.getOutputsList())
     tx.addOutput(
         new TransactionOutput(
             params, tx, Coin.valueOf(output.getAmount()), output.getScript().toByteArray()));
   return Wallet.SendRequest.forTx(tx).fromPaymentDetails(paymentDetails);
 }
示例#5
0
 private void parsePaymentRequest(Protos.PaymentRequest request) throws PaymentRequestException {
   try {
     if (request == null) throw new PaymentRequestException("request cannot be null");
     if (request.getPaymentDetailsVersion() != 1)
       throw new PaymentRequestException.InvalidVersion(
           "Version 1 required. Received version " + request.getPaymentDetailsVersion());
     paymentRequest = request;
     if (!request.hasSerializedPaymentDetails())
       throw new PaymentRequestException("No PaymentDetails");
     paymentDetails =
         Protos.PaymentDetails.newBuilder()
             .mergeFrom(request.getSerializedPaymentDetails())
             .build();
     if (paymentDetails == null) throw new PaymentRequestException("Invalid PaymentDetails");
     if (!paymentDetails.hasNetwork()) params = MainNetParams.get();
     else params = NetworkParameters.fromPmtProtocolID(paymentDetails.getNetwork());
     if (params == null)
       throw new PaymentRequestException.InvalidNetwork(
           "Invalid network " + paymentDetails.getNetwork());
     if (paymentDetails.getOutputsCount() < 1)
       throw new PaymentRequestException.InvalidOutputs("No outputs");
     for (Protos.Output output : paymentDetails.getOutputsList()) {
       if (output.hasAmount()) totalValue = totalValue.add(BigInteger.valueOf(output.getAmount()));
     }
     // This won't ever happen in practice. It would only happen if the user provided outputs
     // that are obviously invalid. Still, we don't want to silently overflow.
     if (totalValue.compareTo(NetworkParameters.MAX_MONEY) > 0)
       throw new PaymentRequestException.InvalidOutputs("The outputs are way too big.");
   } catch (InvalidProtocolBufferException e) {
     throw new PaymentRequestException(e);
   }
 }
 private Protos.PaymentRequest newSimplePaymentRequest() {
   Protos.Output.Builder outputBuilder =
       Protos.Output.newBuilder()
           .setAmount(nanoCoins.longValue())
           .setScript(ByteString.copyFrom(outputToMe.getScriptBytes()));
   Protos.PaymentDetails paymentDetails =
       Protos.PaymentDetails.newBuilder()
           .setNetwork("test")
           .setTime(time)
           .setPaymentUrl(simplePaymentUrl)
           .addOutputs(outputBuilder)
           .setMemo(paymentRequestMemo)
           .setMerchantData(merchantData)
           .build();
   Protos.PaymentRequest paymentRequest =
       Protos.PaymentRequest.newBuilder()
           .setPaymentDetailsVersion(1)
           .setPkiType("none")
           .setSerializedPaymentDetails(paymentDetails.toByteString())
           .build();
   return paymentRequest;
 }
示例#7
0
 /**
  * Generates a Payment message and sends the payment to the merchant who sent the PaymentRequest.
  * Provide transactions built by the wallet. NOTE: This does not broadcast the transactions to the
  * bitcoin network, it merely sends a Payment message to the merchant confirming the payment.
  * Returns an object wrapping PaymentACK once received. If the PaymentRequest did not specify a
  * payment_url, returns null and does nothing.
  *
  * @param txns list of transactions to be included with the Payment message.
  * @param refundAddr will be used by the merchant to send money back if there was a problem.
  * @param memo is a message to include in the payment message sent to the merchant.
  */
 public @Nullable ListenableFuture<Ack> sendPayment(
     List<Transaction> txns, @Nullable Address refundAddr, @Nullable String memo)
     throws PaymentRequestException, VerificationException, IOException {
   Protos.Payment payment = getPayment(txns, refundAddr, memo);
   if (payment == null) return null;
   if (isExpired()) throw new PaymentRequestException.Expired("PaymentRequest is expired");
   URL url;
   try {
     url = new URL(paymentDetails.getPaymentUrl());
   } catch (MalformedURLException e) {
     throw new PaymentRequestException.InvalidPaymentURL(e);
   }
   return sendPayment(url, payment);
 }
 /**
  * Generates a Payment message based on the information in the PaymentRequest. Provide
  * transactions built by the wallet. If the PaymentRequest did not specify a payment_url, returns
  * null.
  *
  * @param txns list of transactions to be included with the Payment message.
  * @param refundAddr will be used by the merchant to send money back if there was a problem.
  * @param memo is a message to include in the payment message sent to the merchant.
  */
 @Nullable
 public Protos.Payment getPayment(
     List<Transaction> txns, @Nullable Address refundAddr, @Nullable String memo)
     throws IOException, PaymentProtocolException.InvalidNetwork {
   if (paymentDetails.hasPaymentUrl()) {
     for (Transaction tx : txns)
       if (!tx.getParams().equals(params))
         throw new PaymentProtocolException.InvalidNetwork(params.getPaymentProtocolId());
     return PaymentProtocol.createPaymentMessage(
         txns, totalValue, refundAddr, memo, getMerchantData());
   } else {
     return null;
   }
 }
示例#9
0
 /**
  * Generates a Payment message based on the information in the PaymentRequest. Provide
  * transactions built by the wallet. If the PaymentRequest did not specify a payment_url, returns
  * null.
  *
  * @param txns list of transactions to be included with the Payment message.
  * @param refundAddr will be used by the merchant to send money back if there was a problem.
  * @param memo is a message to include in the payment message sent to the merchant.
  */
 public @Nullable Protos.Payment getPayment(
     List<Transaction> txns, @Nullable Address refundAddr, @Nullable String memo)
     throws IOException {
   if (!paymentDetails.hasPaymentUrl()) return null;
   Protos.Payment.Builder payment = Protos.Payment.newBuilder();
   if (paymentDetails.hasMerchantData()) payment.setMerchantData(paymentDetails.getMerchantData());
   if (refundAddr != null) {
     Protos.Output.Builder refundOutput = Protos.Output.newBuilder();
     refundOutput.setAmount(totalValue.longValue());
     refundOutput.setScript(
         ByteString.copyFrom(ScriptBuilder.createOutputScript(refundAddr).getProgram()));
     payment.addRefundTo(refundOutput);
   }
   if (memo != null) {
     payment.setMemo(memo);
   }
   for (Transaction txn : txns) {
     txn.verify();
     ByteArrayOutputStream o = new ByteArrayOutputStream();
     txn.bitcoinSerialize(o);
     payment.addTransactions(ByteString.copyFrom(o.toByteArray()));
   }
   return payment.build();
 }
示例#10
0
  /**
   * Create a payment request. You may want to sign the request using {@link #signPaymentRequest}.
   * Use {@link Protos.PaymentRequest.Builder#build} to get the actual payment request.
   *
   * @param params network parameters
   * @param outputs list of outputs to request coins to
   * @param memo arbitrary, user readable memo, or null if none
   * @param paymentUrl URL to send payment message to, or null if none
   * @param merchantData arbitrary merchant data, or null if none
   * @return created payment request, in its builder form
   */
  public static Protos.PaymentRequest.Builder createPaymentRequest(
      NetworkParameters params,
      List<Protos.Output> outputs,
      @Nullable String memo,
      @Nullable String paymentUrl,
      @Nullable byte[] merchantData) {
    final Protos.PaymentDetails.Builder paymentDetails = Protos.PaymentDetails.newBuilder();
    paymentDetails.setNetwork(params.getPaymentProtocolId());
    for (Protos.Output output : outputs) paymentDetails.addOutputs(output);
    if (memo != null) paymentDetails.setMemo(memo);
    if (paymentUrl != null) paymentDetails.setPaymentUrl(paymentUrl);
    if (merchantData != null) paymentDetails.setMerchantData(ByteString.copyFrom(merchantData));
    paymentDetails.setTime(Utils.currentTimeSeconds());

    final Protos.PaymentRequest.Builder paymentRequest = Protos.PaymentRequest.newBuilder();
    paymentRequest.setSerializedPaymentDetails(paymentDetails.build().toByteString());
    return paymentRequest;
  }
示例#11
0
 /** Returns the memo included by the merchant in the payment request, or null if not found. */
 @Nullable
 public String getMemo() {
   if (paymentDetails.hasMemo()) return paymentDetails.getMemo();
   else return null;
 }
示例#12
0
 /**
  * Returns the payment url where the Payment message should be sent. Returns null if no payment
  * url was provided in the PaymentRequest.
  */
 public @Nullable String getPaymentUrl() {
   if (paymentDetails.hasPaymentUrl()) return paymentDetails.getPaymentUrl();
   return null;
 }
示例#13
0
 /** This should always be called before attempting to call sendPayment. */
 public boolean isExpired() {
   return paymentDetails.hasExpires()
       && System.currentTimeMillis() / 1000L > paymentDetails.getExpires();
 }
示例#14
0
 /** Returns the date that the payment request was generated. */
 public Date getDate() {
   return new Date(paymentDetails.getTime() * 1000);
 }
示例#15
0
 /** Returns the expires time of the payment request, or null if none. */
 @Nullable
 public Date getExpires() {
   if (paymentDetails.hasExpires()) return new Date(paymentDetails.getExpires() * 1000);
   else return null;
 }
示例#16
0
 /** Returns the memo included by the merchant in the payment request. */
 public String getMemo() {
   return paymentDetails.getMemo();
 }
示例#17
0
 /** Returns the merchant data included by the merchant in the payment request, or null if none. */
 @Nullable
 public byte[] getMerchantData() {
   if (paymentDetails.hasMerchantData()) return paymentDetails.getMerchantData().toByteArray();
   else return null;
 }